]> git.8kb.co.uk Git - pgpool-ii/pgpool-ii_2.2.5/commitdiff
Attempt to send a proper failure message to frontend when authentication master
authorglyn <glyn@8kb.co.uk>
Mon, 2 Nov 2009 20:36:11 +0000 (20:36 +0000)
committerglyn <glyn@8kb.co.uk>
Mon, 2 Nov 2009 20:36:11 +0000 (20:36 +0000)
fails rather than "server closed the connection unexpectedly".

EDIT: Committed
"http://git.postgresql.org/gitweb/?p=pgpool2.git;a=commit;h=810b44217e16767c4206d183d290cee56a5fd5c8"

pool.h
pool_auth.c
pool_process_query.c

diff --git a/pool.h b/pool.h
index 674a2b527341156f67fcd846a9e21912f06f01b8..6b78b632fd56e0ec94bb4c94ff471d7341546b10 100644 (file)
--- a/pool.h
+++ b/pool.h
@@ -523,6 +523,21 @@ extern void pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor,
                                                         char *hint,
                                                         char *file,
                                                         int line);
                                                         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);
 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);
index cd5bf4233e59a54e85229ec10b4a51da79b1f2c3..def2ebcba81695b1d27b66cf1970091223fafc3a 100644 (file)
 #endif
 #include <errno.h>
 #include <string.h>
 #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);
 
 #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);
 
 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.
 */
 /*
 * do authentication against backend. if success return 0 otherwise non 0.
 */
@@ -136,6 +139,7 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
                msglen = htonl(0);
                if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0)
                {
                msglen = htonl(0);
                if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0)
                {
+                       pool_send_auth_fail(frontend, cp);
                        return -1;
                }
                MASTER(cp)->auth_kind = 0;
                        return -1;
                }
                MASTER(cp)->auth_kind = 0;
@@ -156,6 +160,7 @@ 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);
                        if (authkind < 0)
                        {
                                pool_error("do_clear_text_password failed in slot %d", i);
+                               pool_send_auth_fail(frontend, cp);
                                return -1;
                        }
                }
                                return -1;
                        }
                }
@@ -176,6 +181,7 @@ 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);
                        if (authkind < 0)
                        {
                                pool_error("do_crypt_text_password failed in slot %d", i);
+                               pool_send_auth_fail(frontend, cp);
                                return -1;
                        }
                }
                                return -1;
                        }
                }
@@ -206,6 +212,7 @@ from pool_read_message_length and recheck the pg_hba.conf settings.");
                        if (authkind < 0)
                        {
                                pool_error("do_md5failed in slot %d", i);
                        if (authkind < 0)
                        {
                                pool_error("do_md5failed in slot %d", i);
+                               pool_send_auth_fail(frontend, cp);
                                return -1;
                        }
                }
                                return -1;
                        }
                }
@@ -410,12 +417,41 @@ int pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp)
        else
        {
                pool_debug("pool_do_reauth: authentication failed");
        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);
 }
 
                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.
 */
 /*
 * send authentication ok to frontend. if success return 0 otherwise non 0.
 */
index 5cf2b6960765475e6446493818dea63a149e7540..60901ff12df3b763cf3664dec3faef9456febc92 100644 (file)
@@ -2447,6 +2447,35 @@ void pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor,
                                                         char *hint,
                                                         char *file,
                                                         int line)
                                                         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
 {
 /*
  * 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 */
                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;
                thislen = Min(thislen, MAXMSGBUF);
                memcpy(data +len, msgbuf, thislen+1);
                len += thislen + 1;