]> granicus.if.org Git - pgbouncer/commitdiff
auth_query: make password loading query configurable
authorMarko Kreen <markokr@gmail.com>
Sat, 16 Nov 2013 19:21:55 +0000 (21:21 +0200)
committerMarko Kreen <markokr@gmail.com>
Sat, 16 Nov 2013 19:21:55 +0000 (21:21 +0200)
doc/config.txt
include/bouncer.h
include/pktbuf.h
src/client.c
src/main.c
src/pktbuf.c

index 43e0fbc05efdfda2eb19a582447dc987d68fc165..9cd390797153f72fa882c0192b12acb3f7647e16 100644 (file)
@@ -115,6 +115,12 @@ any::
       databases are configured to log in as specific user.  Additionally, the console
       database allows any user to log in as admin.
 
+==== auth_query ====
+
+Query to load user's password from db.
+
+Default: SELECT usename, passwd FROM pg_shadow WHERE usename=$1
+
 ==== pool_mode ====
 
 Specifies when a server connection can be reused by other clients.
index ad6032e2ef0c32b9b5c9ac6e784b1f82fea32bf4..a8437b757c258dd42ae13385ca3a1aee52a94f9b 100644 (file)
@@ -400,6 +400,7 @@ extern usec_t cf_dns_zone_check_period;
 
 extern int cf_auth_type;
 extern char *cf_auth_file;
+extern char *cf_auth_query;
 
 extern char *cf_pidfile;
 
index 24d773a8c2920d51eb44017353a1dea8a2924d39..9ed0e935df6e3d9f9d9b2eb97e335a8da4463ca7 100644 (file)
@@ -73,6 +73,7 @@ void pktbuf_finish_packet(PktBuf *buf);
 void pktbuf_write_generic(PktBuf *buf, int type, const char *fmt, ...);
 void pktbuf_write_RowDescription(PktBuf *buf, const char *tupdesc, ...);
 void pktbuf_write_DataRow(PktBuf *buf, const char *tupdesc, ...);
+void pktbuf_write_ExtQuery(PktBuf *buf, const char *query, int nargs, ...);
 
 /*
  * Shortcuts for actual packets.
index 5662f619a1f412b20620329913fcceda29fd7741..8ad9b177510d085d09e507f0e448ce152e9ff5c3 100644 (file)
@@ -92,7 +92,7 @@ static bool send_client_authreq(PgSocket *client)
 static void start_auth_request(PgSocket *client, const char *username)
 {
        int res;
-       char quoted_username[64], query[128];
+       PktBuf *buf;
 
        client->auth_user = client->db->auth_user;
        /* have to fetch user info from db */
@@ -111,9 +111,18 @@ static void start_auth_request(PgSocket *client, const char *username)
        }
        client->link->ready = 0;
 
-       pg_quote_literal(quoted_username, username, sizeof(quoted_username));
-       snprintf(query, sizeof(query), "SELECT usename, passwd FROM pg_shadow WHERE usename=%s", quoted_username);
-       SEND_generic(res, client->link, 'Q', "s", query);
+       res = 0;
+       buf = pktbuf_dynamic(512);
+       if (buf) {
+               pktbuf_write_ExtQuery(buf, cf_auth_query, 1, username);
+               res = pktbuf_send_immediate(buf, client->link);
+               pktbuf_free(buf);
+               /*
+                * Should do instead:
+                *   res = pktbuf_send_queued(buf, client->link);
+                * but that needs better integration with SBuf.
+                */
+       }
        if (!res)
                disconnect_server(client->link, false, "unable to send login query");
 }
@@ -281,6 +290,10 @@ bool handle_auth_response(PgSocket *client, PktHdr *pkt) {
                break;
        case 'C':       /* CommandComplete */
                break;
+       case '1':       /* ParseComplete */
+               break;
+       case '2':       /* BindComplete */
+               break;
        case 'Z':       /* ReadyForQuery */
                sbuf_prepare_skip(&client->link->sbuf, pkt->len);
                if (!client->auth_user) {
index 9ef693a03db630dcbb393b7e6cfc9a3bb9ef4615..d978bf1d35e6faf64ca05cd5feeae483ad898614 100644 (file)
@@ -86,6 +86,7 @@ int cf_tcp_keepintvl;
 
 int cf_auth_type = AUTH_MD5;
 char *cf_auth_file;
+char *cf_auth_query;
 
 int cf_max_client_conn;
 int cf_default_pool_size;
@@ -177,6 +178,7 @@ CF_ABS("unix_socket_group", CF_STR, cf_unix_socket_group, CF_NO_RELOAD, ""),
 #endif
 CF_ABS("auth_type", CF_LOOKUP(auth_type_map), cf_auth_type, 0, "md5"),
 CF_ABS("auth_file", CF_STR, cf_auth_file, 0, "unconfigured_file"),
+CF_ABS("auth_query", CF_STR, cf_auth_query, 0, "SELECT usename, passwd FROM pg_shadow WHERE usename=$1"),
 CF_ABS("pool_mode", CF_LOOKUP(pool_mode_map), cf_pool_mode, 0, "session"),
 CF_ABS("max_client_conn", CF_INT, cf_max_client_conn, 0, "100"),
 CF_ABS("default_pool_size", CF_INT, cf_default_pool_size, 0, "20"),
index 6be1d855c5b1a6dc018b8fdf7394e4e9011decc9..23d2689e7e4a2e0782ae1c28f8340c9db7cbd3b3 100644 (file)
@@ -429,3 +429,44 @@ void pktbuf_write_DataRow(PktBuf *buf, const char *tupdesc, ...)
        pktbuf_finish_packet(buf);
 }
 
+/*
+ * Send Parse+Bind+Execute with string parameters.
+ */
+void pktbuf_write_ExtQuery(PktBuf *buf, const char *query, int nargs, ...)
+{
+       va_list ap;
+       const char *val;
+       int len, i;
+
+       /* Parse */
+       pktbuf_write_generic(buf, 'P', "csh", 0, query, 0);
+
+       /* Bind */
+       pktbuf_start_packet(buf, 'B');
+       pktbuf_put_char(buf, 0);        /* portal name */
+       pktbuf_put_char(buf, 0);        /* query name */
+       pktbuf_put_uint16(buf, 0);      /* number of parameter format codes */
+       pktbuf_put_uint16(buf, nargs);  /* number of parameter values */
+
+       va_start(ap, nargs);
+       for (i = 0; i < nargs; i++) {
+               val = va_arg(ap, char *);
+               len = strlen(val);
+               pktbuf_put_uint32(buf, len);
+               pktbuf_put_bytes(buf, val, len);
+       }
+       va_end(ap);
+
+       pktbuf_put_uint16(buf, 0);      /* number of result-column format codes */
+       pktbuf_finish_packet(buf);
+
+       /* Describe */
+       pktbuf_write_generic(buf, 'D', "cc", 'P', 0);
+
+       /* Execute */
+       pktbuf_write_generic(buf, 'E', "ci", 0, 0);
+
+       /* Sync */
+       pktbuf_write_generic(buf, 'S', "");
+}
+