pgpool2.git / summary / log / commit / refs
commit 810b44217e16767c4206d183d290cee56a5fd5c8
Author: Tatsuo Ishii <ishii at sraoss.co.jp>
Date: Tue Nov 03 02:00:39 2009 +0000
When authentication fails, report to frontend proper error messages,
rather than unhelpfull "server closed the connection unexpectedly"
message. Patch provided by Glyn Astill with minor tweak by Tatsuo Ishii.
pool.h | 15 +++++++++++++
pool_auth.c | 59 +++++++++++++++++++++++++++++++++++++++++-----------
pool_process_query.c | 31 ++++++++++++++++++++++++++-
3 files changed, 92 insertions(+), 13 deletions(-)
diff --git a/pool.h b/pool.h
index 2091fb610..bd1d3b609 100644
--- a/pool.h
+++ b/pool.h
@@ -564,6 +564,21 @@ extern void pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor,
char *hint,
char *file,
int line);
+extern void pool_send_fatal_message(POOL_CONNECTION *frontend, int protoMajor,
+ char *code,
+ char *message,
+ char *detail,
+ char *hint,
+ char *file,
+ int line);
+extern void pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor,
+ char *code,
+ char *message,
+ char *detail,
+ char *hint,
+ char *file,
+ char *severity,
+ int line);
extern void pool_send_readyforquery(POOL_CONNECTION *frontend);
extern int send_startup_packet(POOL_CONNECTION_POOL_SLOT *cp);
extern void pool_free_startup_packet(StartupPacket *sp);
diff --git a/pool_auth.c b/pool_auth.c
index c221e950f..2a4c64fa5 100644
--- a/pool_auth.c
+++ b/pool_auth.c
@@ -5,7 +5,7 @@
* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
*
- * Copyright (c) 2003-2008 PgPool Global Development Group
+ * Copyright (c) 2003-2009 PgPool Global Development Group
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
@@ -35,14 +35,17 @@
#endif
#include <errno.h>
#include <string.h>
+#include <stdlib.h>
#define AUTHFAIL_ERRORCODE "28000"
static POOL_STATUS pool_send_auth_ok(POOL_CONNECTION *frontend, int pid, int key, int protoMajor);
static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor);
+static void pool_send_auth_fail(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp);
static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor);
static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor);
+
/*
* do authentication against backend. if success return 0 otherwise non 0.
*/
@@ -155,7 +158,8 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
if (authkind < 0)
{
- pool_error("do_clear_text_password failed in slot %d", i);
+ pool_debug("do_clear_text_password failed in slot %d", i);
+ pool_send_auth_fail(frontend, cp);
return -1;
}
}
@@ -175,7 +179,8 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
if (authkind < 0)
{
- pool_error("do_crypt_text_password failed in slot %d", i);
+ pool_debug("do_crypt_text_password failed in slot %d", i);
+ pool_send_auth_fail(frontend, cp);
return -1;
}
}
@@ -205,7 +210,8 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
if (authkind < 0)
{
- pool_error("do_md5failed in slot %d", i);
+ pool_debug("do_md5failed in slot %d", i);
+ pool_send_auth_fail(frontend, cp);
return -1;
}
}
@@ -219,7 +225,7 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
if (authkind != 0)
{
- pool_error("pool_do_auth: backend does not return authentication ok");
+ pool_error("pool_do_auth: unknown authentication response from backend %d", authkind);
return -1;
}
@@ -410,12 +416,41 @@ int pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp)
else
{
pool_debug("pool_do_reauth: authentication failed");
+ pool_send_auth_fail(frontend, cp);
return -1;
}
return (pool_send_auth_ok(frontend, MASTER_CONNECTION(cp)->pid, MASTER_CONNECTION(cp)->key, protoMajor) != POOL_CONTINUE);
}
+/*
+* send authentication failure message text to frontend
+*/
+static void pool_send_auth_fail(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp)
+{
+ int messagelen;
+ char *errmessage;
+ int protoMajor;
+
+ bool send_error_to_frontend = true;
+
+ protoMajor = MAJOR(cp);
+
+ messagelen = strlen(MASTER_CONNECTION(cp)->sp->user) + 100;
+ if ((errmessage = (char *)malloc(messagelen+1)) == NULL)
+ {
+ pool_error("pool_send_auth_fail_failed: malloc failed: %s", strerror(errno));
+ child_exit(1);
+ }
+
+ snprintf(errmessage, messagelen, "password authentication failed for user \"%s\"",
+ MASTER_CONNECTION(cp)->sp->user);
+ if (send_error_to_frontend)
+ pool_send_fatal_message(frontend, protoMajor, "XX000", errmessage,
+ "", "", __FILE__, __LINE__);
+ free(errmessage);
+}
+
/*
* send authentication ok to frontend. if success return 0 otherwise non 0.
*/
@@ -486,7 +521,7 @@ static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *fro
{
if (pool_read(frontend, &size, sizeof(size)))
{
- pool_error("do_clear_text_password: failed to read password packet size");
+ pool_debug("do_clear_text_password: failed to read password packet size");
return -1;
}
}
@@ -496,7 +531,7 @@ static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *fro
if (pool_read(frontend, &k, sizeof(k)))
{
- pool_error("do_clear_text_password: failed to read password packet \"p\"");
+ pool_debug("do_clear_text_password: failed to read password packet \"p\"");
return -1;
}
if (k != 'p')
@@ -664,7 +699,7 @@ static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int rea
if (pool_read(frontend, &k, sizeof(k)))
{
- pool_error("do_crypt_password: failed to read password packet \"p\"");
+ pool_debug("do_crypt_password: failed to read password packet \"p\"");
return -1;
}
if (k != 'p')
@@ -732,13 +767,13 @@ static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int rea
{
if (pool_read(backend, &len, sizeof(len)))
{
- pool_error("do_clear_text_password: failed to read authentication packet size");
+ pool_error("do_crypt: failed to read authentication packet size");
return -1;
}
if (ntohl(len) != 8)
{
- pool_error("do_clear_text_password: incorrect authentication packet size (%d)", ntohl(len));
+ pool_error("do_crypt: incorrect authentication packet size (%d)", ntohl(len));
return -1;
}
}
@@ -833,7 +868,7 @@ static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reaut
if (pool_read(frontend, &k, sizeof(k)))
{
- pool_error("do_md5_password: failed to read password packet \"p\"");
+ pool_debug("do_md5_password: failed to read password packet \"p\"");
return -1;
}
if (k != 'p')
@@ -906,7 +941,7 @@ static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reaut
if (ntohl(len) != 8)
{
- pool_error("do_clear_text_password: incorrect authentication packet size (%d)", ntohl(len));
+ pool_error("do_md5: incorrect authentication packet size (%d)", ntohl(len));
return -1;
}
}
diff --git a/pool_process_query.c b/pool_process_query.c
index 08694c6e3..4e1e5b83d 100644
--- a/pool_process_query.c
+++ b/pool_process_query.c
@@ -2447,6 +2447,35 @@ void pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor,
char *hint,
char *file,
int line)
+{
+ pool_send_severity_message(frontend, protoMajor, code, message, detail, hint, file, "ERROR", line);
+}
+
+/*
+ * send fatal message to frontend
+ */
+void pool_send_fatal_message(POOL_CONNECTION *frontend, int protoMajor,
+ char *code,
+ char *message,
+ char *detail,
+ char *hint,
+ char *file,
+ int line)
+{
+ pool_send_severity_message(frontend, protoMajor, code, message, detail, hint, file, "FATAL", line);
+}
+
+/*
+ * send severity message to frontend
+ */
+void pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor,
+ char *code,
+ char *message,
+ char *detail,
+ char *hint,
+ char *file,
+ char *severity,
+ int line)
{
/*
* Buffer length for each message part
@@ -2479,7 +2508,7 @@ void pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor,
pool_write(frontend, "E", 1);
/* error level */
- thislen = snprintf(msgbuf, MAXMSGBUF, "SERROR");
+ thislen = snprintf(msgbuf, MAXMSGBUF, "S%s", severity);
thislen = Min(thislen, MAXMSGBUF);
memcpy(data +len, msgbuf, thislen+1);
len += thislen + 1;
[parent: 4b4ad5d7ff78]