Rename SQL data types so they don't conflict with drivers
[freeradius.git] / src / modules / rlm_sql / rlm_sql.c
index 3cca8b3..6dd6c19 100644 (file)
@@ -1,14 +1,7 @@
-
 /*
- * rlm_sql.c           SQL Module
- *             Main SQL module file. Most ICRADIUS code is located in sql.c
- *
- * Version:    $Id$
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
+ *   This program is is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License, version 2 if the
+ *   License as published by the Free Software Foundation.
  *
  *   This program is distributed in the hope that it will be useful,
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+/**
+ * $Id$
+ * @file rlm_sql.c
+ * @brief Implements SQL 'users' file, and SQL accounting.
  *
- * Copyright 2012  Arran Cudbard-Bell <a.cudbardb@freeradius.org>
- * Copyright 2000,2006  The FreeRADIUS server project
- * Copyright 2000  Mike Machado <mike@innercite.com>
- * Copyright 2000  Alan DeKok <aland@ox.org>
+ * @copyright 2012  Arran Cudbard-Bell <a.cudbardb@freeradius.org>
+ * @copyright 2000,2006  The FreeRADIUS server project
+ * @copyright 2000  Mike Machado <mike@innercite.com>
+ * @copyright 2000  Alan DeKok <aland@ox.org>
  */
-
 #include <freeradius-devel/ident.h>
 RCSID("$Id$")
 
@@ -50,59 +48,59 @@ static const CONF_PARSER acct_section_config[] = {
 
 static const CONF_PARSER module_config[] = {
        {"driver", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,sql_driver), NULL, "mysql"},
+        offsetof(rlm_sql_config_t,sql_driver), NULL, "mysql"},
        {"server", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,sql_server), NULL, "localhost"},
+        offsetof(rlm_sql_config_t,sql_server), NULL, "localhost"},
        {"port", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,sql_port), NULL, ""},
+        offsetof(rlm_sql_config_t,sql_port), NULL, ""},
        {"login", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,sql_login), NULL, ""},
+        offsetof(rlm_sql_config_t,sql_login), NULL, ""},
        {"password", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,sql_password), NULL, ""},
+        offsetof(rlm_sql_config_t,sql_password), NULL, ""},
        {"radius_db", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,sql_db), NULL, "radius"},
+        offsetof(rlm_sql_config_t,sql_db), NULL, "radius"},
        {"filename", PW_TYPE_FILENAME, /* for sqlite */
-        offsetof(SQL_CONFIG,sql_file), NULL, NULL},
+        offsetof(rlm_sql_config_t,sql_file), NULL, NULL},
        {"read_groups", PW_TYPE_BOOLEAN,
-        offsetof(SQL_CONFIG,read_groups), NULL, "yes"},
+        offsetof(rlm_sql_config_t,read_groups), NULL, "yes"},
        {"readclients", PW_TYPE_BOOLEAN,
-        offsetof(SQL_CONFIG,do_clients), NULL, "no"},
+        offsetof(rlm_sql_config_t,do_clients), NULL, "no"},
        {"deletestalesessions", PW_TYPE_BOOLEAN,
-        offsetof(SQL_CONFIG,deletestalesessions), NULL, "yes"},
+        offsetof(rlm_sql_config_t,deletestalesessions), NULL, "yes"},
        {"sql_user_name", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,query_user), NULL, ""},
+        offsetof(rlm_sql_config_t,query_user), NULL, ""},
        {"logfile", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,logfile), NULL, NULL},
+        offsetof(rlm_sql_config_t,logfile), NULL, NULL},
        {"default_user_profile", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,default_profile), NULL, ""},
+        offsetof(rlm_sql_config_t,default_profile), NULL, ""},
        {"nas_query", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,nas_query), NULL,
+        offsetof(rlm_sql_config_t,nas_query), NULL,
         "SELECT id,nasname,shortname,type,secret FROM nas"},
        {"authorize_check_query", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,authorize_check_query), NULL, ""},
+        offsetof(rlm_sql_config_t,authorize_check_query), NULL, ""},
        {"authorize_reply_query", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,authorize_reply_query), NULL, NULL},
+        offsetof(rlm_sql_config_t,authorize_reply_query), NULL, NULL},
        {"authorize_group_check_query", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,authorize_group_check_query), NULL, ""},
+        offsetof(rlm_sql_config_t,authorize_group_check_query), NULL, ""},
        {"authorize_group_reply_query", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,authorize_group_reply_query), NULL, ""},
+        offsetof(rlm_sql_config_t,authorize_group_reply_query), NULL, ""},
        {"group_membership_query", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,groupmemb_query), NULL, NULL},
+        offsetof(rlm_sql_config_t,groupmemb_query), NULL, NULL},
 #ifdef WITH_SESSION_MGMT
        {"simul_count_query", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,simul_count_query), NULL, ""},
+        offsetof(rlm_sql_config_t,simul_count_query), NULL, ""},
        {"simul_verify_query", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,simul_verify_query), NULL, ""},
+        offsetof(rlm_sql_config_t,simul_verify_query), NULL, ""},
 #endif
        {"safe-characters", PW_TYPE_STRING_PTR,
-        offsetof(SQL_CONFIG,allowed_chars), NULL,
+        offsetof(rlm_sql_config_t,allowed_chars), NULL,
        "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /"},
 
        /*
         *      This only works for a few drivers.
         */
        {"query_timeout", PW_TYPE_INTEGER,
-        offsetof(SQL_CONFIG,query_timeout), NULL, NULL},
+        offsetof(rlm_sql_config_t,query_timeout), NULL, NULL},
         
        {NULL, -1, 0, NULL, NULL}
 };
@@ -113,17 +111,15 @@ static const CONF_PARSER module_config[] = {
 static int fallthrough(VALUE_PAIR *vp)
 {
        VALUE_PAIR *tmp;
-       tmp = pairfind(vp, PW_FALL_THROUGH, 0);
+       tmp = pairfind(vp, PW_FALL_THROUGH, 0, TAG_ANY);
 
        return tmp ? tmp->vp_integer : 0;
 }
 
-
-
 /*
  *     Yucky prototype.
  */
-static int generate_sql_clients(SQL_INST *inst);
+static int generate_sql_clients(rlm_sql_t *inst);
 static size_t sql_escape_func(REQUEST *, char *out, size_t outlen, const char *in, void *arg);
 
 /*
@@ -136,9 +132,9 @@ static size_t sql_escape_func(REQUEST *, char *out, size_t outlen, const char *i
 static size_t sql_xlat(void *instance, REQUEST *request,
                    const char *fmt, char *out, size_t freespace)
 {
-       SQLSOCK *sqlsocket;
-       SQL_ROW row;
-       SQL_INST *inst = instance;
+       rlm_sql_handle_t *handle;
+       rlm_sql_row_t row;
+       rlm_sql_t *inst = instance;
        char querystr[MAX_QUERY_LEN];
        size_t ret = 0;
 
@@ -159,8 +155,8 @@ static size_t sql_xlat(void *instance, REQUEST *request,
                return 0;
        }
 
-       sqlsocket = sql_get_socket(inst);
-       if (sqlsocket == NULL)
+       handle = sql_get_socket(inst);
+       if (handle == NULL)
                return 0;
 
        rlm_sql_query_log(inst, request, NULL, querystr);
@@ -175,13 +171,13 @@ static size_t sql_xlat(void *instance, REQUEST *request,
                int numaffected;
                char buffer[21]; /* 64bit max is 20 decimal chars + null byte */
 
-               if (rlm_sql_query(&sqlsocket,inst,querystr)) {
-                       sql_release_socket(inst,sqlsocket);
+               if (rlm_sql_query(&handle,inst,querystr)) {
+                       sql_release_socket(inst,handle);
                        
                        return 0;
                }
               
-               numaffected = (inst->module->sql_affected_rows)(sqlsocket,
+               numaffected = (inst->module->sql_affected_rows)(handle,
                                                                inst->config);
                if (numaffected < 1) {
                        RDEBUG("rlm_sql (%s): SQL query affected no rows",
@@ -201,51 +197,51 @@ static size_t sql_xlat(void *instance, REQUEST *request,
                if (ret >= freespace){
                        RDEBUG("rlm_sql (%s): Can't write result, insufficient string space",
                               inst->config->xlat_name);
-                       (inst->module->sql_finish_query)(sqlsocket,
+                       (inst->module->sql_finish_query)(handle,
                                                         inst->config);
-                       sql_release_socket(inst,sqlsocket);
+                       sql_release_socket(inst,handle);
                        return 0;
                }
                
                memcpy(out, buffer, ret + 1); /* we did bounds checking above */
 
-               (inst->module->sql_finish_query)(sqlsocket, inst->config);
-               sql_release_socket(inst,sqlsocket);
+               (inst->module->sql_finish_query)(handle, inst->config);
+               sql_release_socket(inst,handle);
                return ret;
        } /* else it's a SELECT statement */
 
-       if (rlm_sql_select_query(&sqlsocket,inst,querystr)){
-               sql_release_socket(inst,sqlsocket);
+       if (rlm_sql_select_query(&handle,inst,querystr)){
+               sql_release_socket(inst,handle);
                return 0;
        }
 
-       ret = rlm_sql_fetch_row(&sqlsocket, inst);
+       ret = rlm_sql_fetch_row(&handle, inst);
        if (ret) {
                RDEBUG("SQL query did not succeed");
-               (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-               sql_release_socket(inst,sqlsocket);
+               (inst->module->sql_finish_select_query)(handle, inst->config);
+               sql_release_socket(inst,handle);
                return 0;
        }
 
-       row = sqlsocket->row;
+       row = handle->row;
        if (row == NULL) {
                RDEBUG("SQL query did not return any results");
-               (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-               sql_release_socket(inst,sqlsocket);
+               (inst->module->sql_finish_select_query)(handle, inst->config);
+               sql_release_socket(inst,handle);
                return 0;
        }
 
        if (row[0] == NULL){
                RDEBUG("Null value in first column");
-               (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-               sql_release_socket(inst,sqlsocket);
+               (inst->module->sql_finish_select_query)(handle, inst->config);
+               sql_release_socket(inst,handle);
                return 0;
        }
        ret = strlen(row[0]);
        if (ret >= freespace){
                RDEBUG("Insufficient string space");
-               (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-               sql_release_socket(inst,sqlsocket);
+               (inst->module->sql_finish_select_query)(handle, inst->config);
+               sql_release_socket(inst,handle);
                return 0;
        }
 
@@ -253,15 +249,15 @@ static size_t sql_xlat(void *instance, REQUEST *request,
 
        RDEBUG("sql_xlat finished");
 
-       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-       sql_release_socket(inst,sqlsocket);
+       (inst->module->sql_finish_select_query)(handle, inst->config);
+       sql_release_socket(inst,handle);
        return ret;
 }
 
-static int generate_sql_clients(SQL_INST *inst)
+static int generate_sql_clients(rlm_sql_t *inst)
 {
-       SQLSOCK *sqlsocket;
-       SQL_ROW row;
+       rlm_sql_handle_t *handle;
+       rlm_sql_row_t row;
        char querystr[MAX_QUERY_LEN];
        RADCLIENT *c;
        char *prefix_ptr = NULL;
@@ -276,16 +272,16 @@ static int generate_sql_clients(SQL_INST *inst)
        DEBUG("rlm_sql (%s) in generate_sql_clients: query is %s",
              inst->config->xlat_name, querystr);
 
-       sqlsocket = sql_get_socket(inst);
-       if (sqlsocket == NULL)
+       handle = sql_get_socket(inst);
+       if (handle == NULL)
                return -1;
-       if (rlm_sql_select_query(&sqlsocket,inst,querystr)){
+       if (rlm_sql_select_query(&handle,inst,querystr)){
                return -1;
        }
 
-       while(rlm_sql_fetch_row(&sqlsocket, inst) == 0) {
+       while(rlm_sql_fetch_row(&handle, inst) == 0) {
                i++;
-               row = sqlsocket->row;
+               row = handle->row;
                if (row == NULL)
                        break;
                /*
@@ -318,8 +314,7 @@ static int generate_sql_clients(SQL_INST *inst)
                DEBUG("rlm_sql (%s): Read entry nasname=%s,shortname=%s,secret=%s",inst->config->xlat_name,
                        row[1],row[2],row[4]);
 
-               c = rad_malloc(sizeof(*c));
-               memset(c, 0, sizeof(*c));
+               c = talloc_zero(inst, RADCLIENT);
 
 #ifdef WITH_DYNAMIC_CLIENTS
                c->dynamic = 1;
@@ -335,7 +330,7 @@ static int generate_sql_clients(SQL_INST *inst)
                        if ((c->prefix < 0) || (c->prefix > 128)) {
                                radlog(L_ERR, "rlm_sql (%s): Invalid Prefix value '%s' for IP.",
                                       inst->config->xlat_name, prefix_ptr + 1);
-                               free(c);
+                               talloc_free(c);
                                continue;
                        }
                        /* Replace '/' with '\0' */
@@ -346,15 +341,15 @@ static int generate_sql_clients(SQL_INST *inst)
                 *      Always get the numeric representation of IP
                 */
                if (ip_hton(row[1], AF_UNSPEC, &c->ipaddr) < 0) {
-                       radlog(L_CONS|L_ERR, "rlm_sql (%s): Failed to look up hostname %s: %s",
+                       radlog(L_ERR, "rlm_sql (%s): Failed to look up hostname %s: %s",
                               inst->config->xlat_name,
                               row[1], fr_strerror());
-                       free(c);
+                       talloc_free(c);
                        continue;
                } else {
                        char buffer[256];
                        ip_ntoh(&c->ipaddr, buffer, sizeof(buffer));
-                       c->longname = strdup(buffer);
+                       c->longname = talloc_strdup(c, buffer);
                }
 
                if (c->prefix < 0) switch (c->ipaddr.af) {
@@ -371,19 +366,19 @@ static int generate_sql_clients(SQL_INST *inst)
                /*
                 *      Other values (secret, shortname, nastype, virtual_server)
                 */
-               c->secret = strdup(row[4]);
-               c->shortname = strdup(row[2]);
+               c->secret = talloc_strdup(c, row[4]);
+               c->shortname = talloc_strdup(c, row[2]);
                if(row[3] != NULL)
                        c->nastype = strdup(row[3]);
 
-               numf = (inst->module->sql_num_fields)(sqlsocket, inst->config);
+               numf = (inst->module->sql_num_fields)(handle, inst->config);
                if ((numf > 5) && (row[5] != NULL) && *row[5]) c->server = strdup(row[5]);
 
                DEBUG("rlm_sql (%s): Adding client %s (%s, server=%s) to clients list",
                      inst->config->xlat_name,
                      c->longname,c->shortname, c->server ? c->server : "<none>");
                if (!client_add(NULL, c)) {
-                       sql_release_socket(inst, sqlsocket);
+                       sql_release_socket(inst, handle);
                        DEBUG("rlm_sql (%s): Failed to add client %s (%s) to clients list.  Maybe there's a duplicate?",
                              inst->config->xlat_name,
                              c->longname,c->shortname);
@@ -391,8 +386,8 @@ static int generate_sql_clients(SQL_INST *inst)
                        return -1;
                }
        }
-       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-       sql_release_socket(inst, sqlsocket);
+       (inst->module->sql_finish_select_query)(handle, inst->config);
+       sql_release_socket(inst, handle);
 
        return 0;
 }
@@ -404,7 +399,7 @@ static int generate_sql_clients(SQL_INST *inst)
 static size_t sql_escape_func(UNUSED REQUEST *request, char *out, size_t outlen,
                              const char *in, void *arg)
 {
-       SQL_INST *inst = arg;
+       rlm_sql_t *inst = arg;
        size_t len = 0;
 
        while (in[0]) {
@@ -457,10 +452,12 @@ static size_t sql_escape_func(UNUSED REQUEST *request, char *out, size_t outlen,
  *     escape it twice. (it will make things wrong if we have an
  *     escape candidate character in the username)
  */
-int sql_set_user(SQL_INST *inst, REQUEST *request, const char *username)
+int sql_set_user(rlm_sql_t *inst, REQUEST *request, const char *username)
 {
+       char buffer[254];
        VALUE_PAIR *vp = NULL;
        const char *sqluser;
+       size_t len;
 
        if (username != NULL) {
                sqluser = username;
@@ -469,14 +466,18 @@ int sql_set_user(SQL_INST *inst, REQUEST *request, const char *username)
        } else {
                return 0;
        }
-
-       vp = pairmake_xlat("SQL-User-Name", sqluser, T_OP_SET);
-       if (!vp) {
+       
+       len = radius_xlat(buffer, sizeof(buffer), sqluser, request, NULL, NULL);
+       if (!len) {
                return -1;
        }
        
-       pairxlatmove(request, &(request->packet->vps), &vp);
-       pairfree(&vp); /* Free the VP if for some reason it wasn't moved */
+       vp = pairalloc(NULL, inst->sql_user);
+       vp->op = T_OP_SET;
+       
+       strlcpy(vp->vp_strvalue, buffer, sizeof(vp->vp_strvalue));
+       vp->length = strlen(vp->vp_strvalue);
+       pairadd(&request->packet->vps, vp);
 
        RDEBUG2("SQL-User-Name updated");
 
@@ -484,9 +485,9 @@ int sql_set_user(SQL_INST *inst, REQUEST *request, const char *username)
 }
 
 
-static void sql_grouplist_free (SQL_GROUPLIST **group_list)
+static void sql_grouplist_free (rlm_sql_grouplist_t **group_list)
 {
-       SQL_GROUPLIST *last;
+       rlm_sql_grouplist_t *last;
 
        while(*group_list) {
                last = *group_list;
@@ -496,12 +497,12 @@ static void sql_grouplist_free (SQL_GROUPLIST **group_list)
 }
 
 
-static int sql_get_grouplist (SQL_INST *inst, SQLSOCK *sqlsocket, REQUEST *request, SQL_GROUPLIST **group_list)
+static int sql_get_grouplist (rlm_sql_t *inst, rlm_sql_handle_t *handle, REQUEST *request, rlm_sql_grouplist_t **group_list)
 {
        char    querystr[MAX_QUERY_LEN];
        int     num_groups = 0;
-       SQL_ROW row;
-       SQL_GROUPLIST   *group_list_tmp;
+       rlm_sql_row_t row;
+       rlm_sql_grouplist_t   *group_list_tmp;
 
        /* NOTE: sql_set_user should have been run before calling this function */
 
@@ -517,32 +518,32 @@ static int sql_get_grouplist (SQL_INST *inst, SQLSOCK *sqlsocket, REQUEST *reque
                return -1;
        }
 
-       if (rlm_sql_select_query(&sqlsocket, inst, querystr) < 0) {
+       if (rlm_sql_select_query(&handle, inst, querystr) < 0) {
                return -1;
        }
-       while (rlm_sql_fetch_row(&sqlsocket, inst) == 0) {
-               row = sqlsocket->row;
+       while (rlm_sql_fetch_row(&handle, inst) == 0) {
+               row = handle->row;
                if (row == NULL)
                        break;
                if (row[0] == NULL){
                        RDEBUG("row[0] returned NULL");
-                       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
+                       (inst->module->sql_finish_select_query)(handle, inst->config);
                        sql_grouplist_free(group_list);
                        return -1;
                }
                if (*group_list == NULL) {
-                       *group_list = rad_malloc(sizeof(SQL_GROUPLIST));
+                       *group_list = rad_malloc(sizeof(rlm_sql_grouplist_t));
                        group_list_tmp = *group_list;
                } else {
                        rad_assert(group_list_tmp != NULL);
-                       group_list_tmp->next = rad_malloc(sizeof(SQL_GROUPLIST));
+                       group_list_tmp->next = rad_malloc(sizeof(rlm_sql_grouplist_t));
                        group_list_tmp = group_list_tmp->next;
                }
                group_list_tmp->next = NULL;
                strlcpy(group_list_tmp->groupname, row[0], MAX_STRING_LEN);
        }
 
-       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
+       (inst->module->sql_finish_select_query)(handle, inst->config);
 
        return num_groups;
 }
@@ -558,16 +559,16 @@ static int sql_get_grouplist (SQL_INST *inst, SQLSOCK *sqlsocket, REQUEST *reque
 static int sql_groupcmp(void *instance, REQUEST *request, VALUE_PAIR *request_vp, VALUE_PAIR *check,
                        VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
 {
-       SQLSOCK *sqlsocket;
-       SQL_INST *inst = instance;
-       SQL_GROUPLIST *group_list, *group_list_tmp;
+       rlm_sql_handle_t *handle;
+       rlm_sql_t *inst = instance;
+       rlm_sql_grouplist_t *group_list, *group_list_tmp;
 
        check_pairs = check_pairs;
        reply_pairs = reply_pairs;
        request_vp = request_vp;
 
        RDEBUG("sql_groupcmp");
-       if (!check || !check->vp_strvalue || !check->length){
+       if (!check || !check->length){
                RDEBUG("sql_groupcmp: Illegal group name");
                return 1;
        }
@@ -584,18 +585,18 @@ static int sql_groupcmp(void *instance, REQUEST *request, VALUE_PAIR *request_vp
        /*
         *      Get a socket for this lookup
         */
-       sqlsocket = sql_get_socket(inst);
-       if (sqlsocket == NULL) {
+       handle = sql_get_socket(inst);
+       if (handle == NULL) {
                return 1;
        }
 
        /*
         *      Get the list of groups this user is a member of
         */
-       if (sql_get_grouplist(inst, sqlsocket, request, &group_list) < 0) {
+       if (sql_get_grouplist(inst, handle, request, &group_list) < 0) {
                radlog_request(L_ERR, 0, request,
                               "Error getting group membership");
-               sql_release_socket(inst, sqlsocket);
+               sql_release_socket(inst, handle);
                return 1;
        }
 
@@ -605,14 +606,14 @@ static int sql_groupcmp(void *instance, REQUEST *request, VALUE_PAIR *request_vp
                               check->vp_strvalue);
                        /* Free the grouplist */
                        sql_grouplist_free(&group_list);
-                       sql_release_socket(inst, sqlsocket);
+                       sql_release_socket(inst, handle);
                        return 0;
                }
        }
 
        /* Free the grouplist */
        sql_grouplist_free(&group_list);
-       sql_release_socket(inst,sqlsocket);
+       sql_release_socket(inst,handle);
 
        RDEBUG("sql_groupcmp finished: User is NOT a member of group %s",
               check->vp_strvalue);
@@ -622,11 +623,11 @@ static int sql_groupcmp(void *instance, REQUEST *request, VALUE_PAIR *request_vp
 
 
 
-static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sqlsocket, int *dofallthrough)
+static int rlm_sql_process_groups(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t *handle, int *dofallthrough)
 {
        VALUE_PAIR *check_tmp = NULL;
        VALUE_PAIR *reply_tmp = NULL;
-       SQL_GROUPLIST *group_list, *group_list_tmp;
+       rlm_sql_grouplist_t *group_list, *group_list_tmp;
        VALUE_PAIR *sql_group = NULL;
        char    querystr[MAX_QUERY_LEN];
        int found = 0;
@@ -635,7 +636,7 @@ static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sql
        /*
         *      Get the list of groups this user is a member of
         */
-       if (sql_get_grouplist(inst, sqlsocket, request, &group_list) < 0) {
+       if (sql_get_grouplist(inst, handle, request, &group_list) < 0) {
                radlog_request(L_ERR, 0, request, "Error retrieving group list");
                return -1;
        }
@@ -657,16 +658,16 @@ static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sql
                        radlog_request(L_ERR, 0, request,
                                       "Error generating query; rejecting user");
                        /* Remove the grouup we added above */
-                       pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, -1);
+                       pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
                        sql_grouplist_free(&group_list);
                        return -1;
                }
-               rows = sql_getvpdata(inst, &sqlsocket, &check_tmp, querystr);
+               rows = sql_getvpdata(inst, &handle, &check_tmp, querystr);
                if (rows < 0) {
                        radlog_request(L_ERR, 0, request, "Error retrieving check pairs for group %s",
                               group_list_tmp->groupname);
                        /* Remove the grouup we added above */
-                       pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, -1);
+                       pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
                        pairfree(&check_tmp);
                        sql_grouplist_free(&group_list);
                        return -1;
@@ -684,24 +685,24 @@ static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sql
                                if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func, inst)) {
                                        radlog_request(L_ERR, 0, request, "Error generating query; rejecting user");
                                        /* Remove the grouup we added above */
-                                       pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, -1);
+                                       pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
                                        pairfree(&check_tmp);
                                        sql_grouplist_free(&group_list);
                                        return -1;
                                }
-                               if (sql_getvpdata(inst, &sqlsocket, &reply_tmp, querystr) < 0) {
+                               if (sql_getvpdata(inst, &handle, &reply_tmp, querystr) < 0) {
                                        radlog_request(L_ERR, 0, request, "Error retrieving reply pairs for group %s",
                                               group_list_tmp->groupname);
                                        /* Remove the grouup we added above */
-                                       pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, -1);
+                                       pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
                                        pairfree(&check_tmp);
                                        pairfree(&reply_tmp);
                                        sql_grouplist_free(&group_list);
                                        return -1;
                                }
                                *dofallthrough = fallthrough(reply_tmp);
-                               pairxlatmove(request, &request->reply->vps, &reply_tmp);
-                               pairxlatmove(request, &request->config_items, &check_tmp);
+                               radius_xlat_move(request, &request->reply->vps, &reply_tmp);
+                               radius_xlat_move(request, &request->config_items, &check_tmp);
                        }
                } else {
                        /*
@@ -719,31 +720,31 @@ static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sql
                        if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func, inst)) {
                                radlog_request(L_ERR, 0, request, "Error generating query; rejecting user");
                                /* Remove the grouup we added above */
-                               pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, -1);
+                               pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
                                pairfree(&check_tmp);
                                sql_grouplist_free(&group_list);
                                return -1;
                        }
-                       if (sql_getvpdata(inst, &sqlsocket, &reply_tmp, querystr) < 0) {
+                       if (sql_getvpdata(inst, &handle, &reply_tmp, querystr) < 0) {
                                radlog_request(L_ERR, 0, request, "Error retrieving reply pairs for group %s",
                                       group_list_tmp->groupname);
                                /* Remove the grouup we added above */
-                               pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, -1);
+                               pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
                                pairfree(&check_tmp);
                                pairfree(&reply_tmp);
                                sql_grouplist_free(&group_list);
                                return -1;
                        }
                        *dofallthrough = fallthrough(reply_tmp);
-                       pairxlatmove(request, &request->reply->vps, &reply_tmp);
-                       pairxlatmove(request, &request->config_items, &check_tmp);
+                       radius_xlat_move(request, &request->reply->vps, &reply_tmp);
+                       radius_xlat_move(request, &request->config_items, &check_tmp);
                }
 
                /*
                 * Delete the Sql-Group we added above
                 * And clear out the pairlists
                 */
-               pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, -1);
+               pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY);
                pairfree(&check_tmp);
                pairfree(&reply_tmp);
        }
@@ -755,47 +756,16 @@ static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sql
 
 static int rlm_sql_detach(void *instance)
 {
-       SQL_INST *inst = instance;
+       rlm_sql_t *inst = instance;
 
        paircompare_unregister(PW_SQL_GROUP, sql_groupcmp);
        
-       if (inst->config->postauth) free(inst->config->postauth);
-       if (inst->config->accounting) free(inst->config->accounting);
-       
        if (inst->config) {
-               int i;
-
                if (inst->pool) sql_poolfree(inst);
 
                if (inst->config->xlat_name) {
                        xlat_unregister(inst->config->xlat_name, sql_xlat, instance);
-                       cfree(inst->config->xlat_name);
-               }
-
-               /*
-                *      Free up dynamically allocated string pointers.
-                */
-               for (i = 0; module_config[i].name != NULL; i++) {
-                       char **p;
-                       if (module_config[i].type != PW_TYPE_STRING_PTR) {
-                               continue;
-                       }
-
-                       /*
-                        *      Treat 'config' as an opaque array of bytes,
-                        *      and take the offset into it.  There's a
-                        *      (char*) pointer at that offset, and we want
-                        *      to point to it.
-                        */
-                       p = (char **) (((char *)inst->config) + module_config[i].offset);
-                       if (!*p) { /* nothing allocated */
-                               continue;
-                       }
-                       free(*p);
-                       *p = NULL;
                }
-               free(inst->config);
-               inst->config = NULL;
        }
 
        if (inst->handle) {
@@ -806,13 +776,12 @@ static int rlm_sql_detach(void *instance)
                lt_dlclose(inst->handle);       /* ignore any errors */
 #endif
        }
-       free(inst);
 
        return 0;
 }
 
 static int parse_sub_section(CONF_SECTION *parent, 
-                            UNUSED SQL_INST *inst,
+                            rlm_sql_t *inst,
                             sql_acct_section_t **config,
                             rlm_components_t comp)
 {
@@ -822,20 +791,18 @@ static int parse_sub_section(CONF_SECTION *parent,
        
        cs = cf_section_sub_find(parent, name);
        if (!cs) {
-               radlog(L_INFO, "Couldn't find configuration for %s. "
-                      "Will return NOOP for calls from this section.", name);
+               radlog(L_INFO, "rlm_sql (%s): Couldn't find configuration for "
+                      "%s, will return NOOP for calls from this section",
+                      inst->config->xlat_name, name);
                
                return 0;
        }
        
-       *config = rad_calloc(sizeof(**config));
+       *config = talloc_zero(parent, sql_acct_section_t);
        if (cf_section_parse(cs, *config, acct_section_config) < 0) {
-               radlog(L_ERR, "Failed parsing configuration for section %s",
-                      name);
-               
-               free(*config);
-               *config = NULL;
-               
+               radlog(L_ERR, "rlm_sql (%s): Couldn't find configuration for "
+                      "%s, will return NOOP for calls from this section",
+                      inst->config->xlat_name, name);
                return -1;
        }
                
@@ -844,12 +811,20 @@ static int parse_sub_section(CONF_SECTION *parent,
        return 0;
 }
 
-static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
+static int rlm_sql_instantiate(CONF_SECTION *conf, void **instance)
 {
-       SQL_INST *inst;
+       rlm_sql_t *inst;
        const char *xlat_name;
 
-       inst = rad_calloc(sizeof(SQL_INST));
+       *instance = inst = talloc_zero(conf, rlm_sql_t);
+       if (!inst) return -1;
+       
+       /*
+        *      Cache the SQL-User-Name DICT_ATTR, so we can be slightly
+        *      more efficient about creating SQL-User-Name attributes.
+        */
+       inst->sql_user = dict_attrbyname("SQL-User-Name");
+       if (!inst->sql_user) return -1;
 
        /*
         *      Export these methods, too.  This avoids RTDL_GLOBAL.
@@ -862,7 +837,7 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
        inst->sql_select_query          = rlm_sql_select_query;
        inst->sql_fetch_row             = rlm_sql_fetch_row;
        
-       inst->config = rad_calloc(sizeof(SQL_CONFIG));
+       inst->config = talloc_zero(inst, rlm_sql_config_t);
        inst->cs = conf;
 
        xlat_name = cf_section_name2(conf);
@@ -870,27 +845,29 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
                xlat_name = cf_section_name1(conf);
        } else {
                char *group_name;
-               DICT_ATTR *dattr;
+               const DICT_ATTR *dattr;
                ATTR_FLAGS flags;
 
                /*
                 *      Allocate room for <instance>-SQL-Group
                 */
-               group_name = rad_malloc((strlen(xlat_name) + 1 + 11) * sizeof(char));
-               sprintf(group_name,"%s-SQL-Group", xlat_name);
+               group_name = talloc_asprintf(inst, "%s-SQL-Group", xlat_name);
                DEBUG("rlm_sql (%s): Creating new attribute %s",
                      xlat_name, group_name);
 
                memset(&flags, 0, sizeof(flags));
-               dict_addattr(group_name, 0, PW_TYPE_STRING, -1, flags);
+               if (dict_addattr(group_name, -1, 0, PW_TYPE_STRING, flags) < 0) {
+                       radlog(L_ERR, "rlm_sql (%s): Failed to create "
+                              "attribute %s: %s", xlat_name, group_name,
+                              fr_strerror());
+                       return -1;
+               }
+
                dattr = dict_attrbyname(group_name);
-               if (dattr == NULL){
+               if (!dattr) {
                        radlog(L_ERR, "rlm_sql (%s): Failed to create "
                               "attribute %s", xlat_name, group_name);
-                              
-                       free(group_name);
-
-                       goto error;
+                       return -1;
                }
 
                if (inst->config->groupmemb_query && 
@@ -900,17 +877,14 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
                        paircompare_register(dattr->attr, PW_USER_NAME,
                                             sql_groupcmp, inst);
                }
-
-               free(group_name);
        }
        
        rad_assert(xlat_name);
-       
 
        /*
         *      Register the SQL xlat function
         */
-       inst->config->xlat_name = strdup(xlat_name);
+       inst->config->xlat_name = talloc_strdup(inst->config, xlat_name);
        xlat_register(xlat_name, sql_xlat, inst);
 
        /*
@@ -925,7 +899,7 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
                               RLM_COMPONENT_POST_AUTH) < 0)) {
                radlog(L_ERR, "rlm_sql (%s): Failed parsing configuration",
                       inst->config->xlat_name);
-               goto error;
+               return -1;
        }
                
        /*
@@ -934,7 +908,7 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
        if (strncmp(inst->config->sql_driver, "rlm_sql_", 8) != 0) {
                radlog(L_ERR, "rlm_sql (%s): \"%s\" is NOT an SQL driver!",
                       inst->config->xlat_name, inst->config->sql_driver);
-               goto error;
+               return -1;
        }
 
        /*
@@ -947,8 +921,7 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
                       lt_dlerror());
                radlog(L_ERR, "Make sure it (and all its dependent libraries!)"
                       "are in the search path of your system's ld.");
-
-               goto error;
+               return -1;
        }
 
        inst->module = (rlm_sql_module_t *) lt_dlsym(inst->handle,
@@ -957,8 +930,7 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
                radlog(L_ERR, "Could not link symbol %s: %s",
                       inst->config->sql_driver,
                       lt_dlerror());
-
-               goto error;
+               return -1;
        }
 
        radlog(L_INFO, "rlm_sql (%s): Driver %s (module %s) loaded and linked",
@@ -973,8 +945,7 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
               inst->config->sql_server, inst->config->sql_port,
               inst->config->sql_db);
               
-       if (sql_init_socketpool(inst) < 0)
-               goto error;
+       if (sql_init_socketpool(inst) < 0) return -1;
 
        if (inst->config->groupmemb_query && 
            inst->config->groupmemb_query[0]) {
@@ -984,28 +955,20 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
        if (inst->config->do_clients) {
                if (generate_sql_clients(inst) == -1){
                        radlog(L_ERR, "Failed to load clients from SQL.");
-                       
-                       goto error;
+                       return -1;
                }
        }
 
-       *instance = inst;
-
        return RLM_MODULE_OK;
-       
-       error:
-       rlm_sql_detach(inst);
-       
-       return -1;
 }
 
 
-static int rlm_sql_authorize(void *instance, REQUEST * request)
+static rlm_rcode_t rlm_sql_authorize(void *instance, REQUEST * request)
 {
        int ret = RLM_MODULE_NOTFOUND;
        
-       SQL_INST *inst = instance;
-       SQLSOCK  *sqlsocket;
+       rlm_sql_t *inst = instance;
+       rlm_sql_handle_t  *handle;
        
        VALUE_PAIR *check_tmp = NULL;
        VALUE_PAIR *reply_tmp = NULL;
@@ -1028,8 +991,8 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
         *  After this point use goto error or goto release to cleanup sockets
         *  temporary pairlists and temporary attributes.
         */
-       sqlsocket = sql_get_socket(inst);
-       if (sqlsocket == NULL)
+       handle = sql_get_socket(inst);
+       if (handle == NULL)
                goto error;
 
        /*
@@ -1044,7 +1007,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                        goto error;
                }
                
-               rows = sql_getvpdata(inst, &sqlsocket, &check_tmp, querystr);
+               rows = sql_getvpdata(inst, &handle, &check_tmp, querystr);
                if (rows < 0) {
                        radlog_request(L_ERR, 0, request, "SQL query error; rejecting user");
        
@@ -1058,7 +1021,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                    (paircompare(request, request->packet->vps, check_tmp, &request->reply->vps) == 0)) {       
                        RDEBUG2("User found in radcheck table");
                        
-                       pairxlatmove(request, &request->config_items, &check_tmp);
+                       radius_xlat_move(request, &request->config_items, &check_tmp);
                        
                        ret = RLM_MODULE_OK;
                }
@@ -1082,7 +1045,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                        goto error;
                }
                
-               rows = sql_getvpdata(inst, &sqlsocket, &reply_tmp, querystr);
+               rows = sql_getvpdata(inst, &handle, &reply_tmp, querystr);
                if (rows < 0) {
                        radlog_request(L_ERR, 0, request, "SQL query error; rejecting user");
 
@@ -1093,7 +1056,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                        if (!inst->config->read_groups)
                                dofallthrough = fallthrough(reply_tmp);
                                
-                       pairxlatmove(request, &request->reply->vps, &reply_tmp);
+                       radius_xlat_move(request, &request->reply->vps, &reply_tmp);
                        
                        ret = RLM_MODULE_OK;
                }
@@ -1114,7 +1077,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
         *  the groups as well.
         */
        if (dofallthrough) {
-               rows = rlm_sql_process_groups(inst, request, sqlsocket, &dofallthrough);
+               rows = rlm_sql_process_groups(inst, request, handle, &dofallthrough);
                if (rows < 0) {
                        radlog_request(L_ERR, 0, request, "Error processing groups; rejecting user");
 
@@ -1132,7 +1095,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                /*
                 *  Check for a default_profile or for a User-Profile.
                 */
-               user_profile = pairfind(request->config_items, PW_USER_PROFILE, 0);
+               user_profile = pairfind(request->config_items, PW_USER_PROFILE, 0, TAG_ANY);
                
                const char *profile = user_profile ?
                                      user_profile->vp_strvalue :
@@ -1149,7 +1112,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                        goto error;
                }
                
-               rows = rlm_sql_process_groups(inst, request, sqlsocket, &dofallthrough);
+               rows = rlm_sql_process_groups(inst, request, handle, &dofallthrough);
                if (rows < 0) {
                        radlog_request(L_ERR, 0, request, "Error processing profile groups; rejecting user");
 
@@ -1166,7 +1129,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
        ret = RLM_MODULE_FAIL;
        
        release:
-       sql_release_socket(inst, sqlsocket);
+       sql_release_socket(inst, handle);
                
        pairfree(&check_tmp);
        pairfree(&reply_tmp);
@@ -1184,12 +1147,12 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
  *     doesn't update any rows, the next matching config item is used.
  *  
  */
-static int acct_redundant(SQL_INST *inst, REQUEST *request, 
+static int acct_redundant(rlm_sql_t *inst, REQUEST *request, 
                          sql_acct_section_t *section)
 {
        int     ret = RLM_MODULE_OK;
 
-       SQLSOCK *sqlsocket = NULL;
+       rlm_sql_handle_t        *handle = NULL;
        int     sql_ret;
        int     numaffected = 0;
 
@@ -1227,8 +1190,8 @@ static int acct_redundant(SQL_INST *inst, REQUEST *request,
        
        RDEBUG2("Using query template '%s'", attr);
        
-       sqlsocket = sql_get_socket(inst);
-       if (sqlsocket == NULL)
+       handle = sql_get_socket(inst);
+       if (handle == NULL)
                return RLM_MODULE_FAIL;
                
        sql_set_user(inst, request, NULL);
@@ -1262,11 +1225,11 @@ static int acct_redundant(SQL_INST *inst, REQUEST *request,
                 *  were exhausted, and we couldn't create a new connection,
                 *  so we do not need to call sql_release_socket.
                 */
-               sql_ret = rlm_sql_query(&sqlsocket, inst, querystr);    
+               sql_ret = rlm_sql_query(&handle, inst, querystr);       
                if (sql_ret == SQL_DOWN)
                        return RLM_MODULE_FAIL;
                
-               rad_assert(sqlsocket);
+               rad_assert(handle);
        
                /* 
                 *  Assume all other errors are incidental, and just meant our
@@ -1274,14 +1237,14 @@ static int acct_redundant(SQL_INST *inst, REQUEST *request,
                 */
                if (sql_ret == 0) {
                        numaffected = (inst->module->sql_affected_rows)
-                                       (sqlsocket, inst->config);
+                                       (handle, inst->config);
                        if (numaffected > 0)
                                break;
                                
                        RDEBUG("No records updated");
                }
 
-               (inst->module->sql_finish_query)(sqlsocket, inst->config);
+               (inst->module->sql_finish_query)(handle, inst->config);
                
                /*
                 *  We assume all entries with the same name form a redundant
@@ -1300,10 +1263,10 @@ static int acct_redundant(SQL_INST *inst, REQUEST *request,
                RDEBUG("Trying next query...");
        }
        
-       (inst->module->sql_finish_query)(sqlsocket, inst->config);
+       (inst->module->sql_finish_query)(handle, inst->config);
 
        release:
-       sql_release_socket(inst, sqlsocket);
+       sql_release_socket(inst, handle);
 
        return ret;
 }
@@ -1313,8 +1276,8 @@ static int acct_redundant(SQL_INST *inst, REQUEST *request,
 /*
  *     Accounting: Insert or update session data in our sql table
  */
-static int rlm_sql_accounting(void *instance, REQUEST * request) {
-       SQL_INST *inst = instance;              
+static rlm_rcode_t rlm_sql_accounting(void *instance, REQUEST * request) {
+       rlm_sql_t *inst = instance;             
 
        if (inst->config->accounting) {
                return acct_redundant(inst, request, inst->config->accounting); 
@@ -1335,10 +1298,10 @@ static int rlm_sql_accounting(void *instance, REQUEST * request) {
  *        logins by querying the terminal server (using eg. SNMP).
  */
 
-static int rlm_sql_checksimul(void *instance, REQUEST * request) {
-       SQLSOCK         *sqlsocket;
-       SQL_INST        *inst = instance;
-       SQL_ROW         row;
+static rlm_rcode_t rlm_sql_checksimul(void *instance, REQUEST * request) {
+       rlm_sql_handle_t        *handle;
+       rlm_sql_t       *inst = instance;
+       rlm_sql_row_t           row;
        char            querystr[MAX_QUERY_LEN];
        int             check = 0;
         uint32_t        ipno = 0;
@@ -1367,34 +1330,34 @@ static int rlm_sql_checksimul(void *instance, REQUEST * request) {
        radius_xlat(querystr, sizeof(querystr), inst->config->simul_count_query, request, sql_escape_func, inst);
 
        /* initialize the sql socket */
-       sqlsocket = sql_get_socket(inst);
-       if(sqlsocket == NULL)
+       handle = sql_get_socket(inst);
+       if(handle == NULL)
                return RLM_MODULE_FAIL;
 
-       if(rlm_sql_select_query(&sqlsocket, inst, querystr)) {
-               sql_release_socket(inst, sqlsocket);
+       if(rlm_sql_select_query(&handle, inst, querystr)) {
+               sql_release_socket(inst, handle);
                return RLM_MODULE_FAIL;
        }
 
-       ret = rlm_sql_fetch_row(&sqlsocket, inst);
+       ret = rlm_sql_fetch_row(&handle, inst);
        if (ret != 0) {
-               (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-               sql_release_socket(inst, sqlsocket);
+               (inst->module->sql_finish_select_query)(handle, inst->config);
+               sql_release_socket(inst, handle);
                return RLM_MODULE_FAIL;
        }
 
-       row = sqlsocket->row;
+       row = handle->row;
        if (row == NULL) {
-               (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-               sql_release_socket(inst, sqlsocket);
+               (inst->module->sql_finish_select_query)(handle, inst->config);
+               sql_release_socket(inst, handle);
                return RLM_MODULE_FAIL;
        }
 
        request->simul_count = atoi(row[0]);
-       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
+       (inst->module->sql_finish_select_query)(handle, inst->config);
 
        if(request->simul_count < request->simul_max) {
-               sql_release_socket(inst, sqlsocket);
+               sql_release_socket(inst, handle);
                return RLM_MODULE_OK;
        }
 
@@ -1404,13 +1367,13 @@ static int rlm_sql_checksimul(void *instance, REQUEST * request) {
         */
        if (!inst->config->simul_verify_query ||
            (inst->config->simul_verify_query[0] == '\0')) {
-               sql_release_socket(inst, sqlsocket);
+               sql_release_socket(inst, handle);
                return RLM_MODULE_OK;
        }
 
        radius_xlat(querystr, sizeof(querystr), inst->config->simul_verify_query, request, sql_escape_func, inst);
-       if(rlm_sql_select_query(&sqlsocket, inst, querystr)) {
-               sql_release_socket(inst, sqlsocket);
+       if(rlm_sql_select_query(&handle, inst, querystr)) {
+               sql_release_socket(inst, handle);
                return RLM_MODULE_FAIL;
        }
 
@@ -1419,25 +1382,25 @@ static int rlm_sql_checksimul(void *instance, REQUEST * request) {
          */
        request->simul_count = 0;
 
-        if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS, 0)) != NULL)
+        if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS, 0, TAG_ANY)) != NULL)
                 ipno = vp->vp_ipaddr;
-        if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID, 0)) != NULL)
+        if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID, 0, TAG_ANY)) != NULL)
                 call_num = vp->vp_strvalue;
 
 
-       while (rlm_sql_fetch_row(&sqlsocket, inst) == 0) {
-               row = sqlsocket->row;
+       while (rlm_sql_fetch_row(&handle, inst) == 0) {
+               row = handle->row;
                if (row == NULL)
                        break;
                if (!row[2]){
-                       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-                       sql_release_socket(inst, sqlsocket);
+                       (inst->module->sql_finish_select_query)(handle, inst->config);
+                       sql_release_socket(inst, handle);
                        RDEBUG("Cannot zap stale entry. No username present in entry.", inst->config->xlat_name);
                        return RLM_MODULE_FAIL;
                }
                if (!row[1]){
-                       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-                       sql_release_socket(inst, sqlsocket);
+                       (inst->module->sql_finish_select_query)(handle, inst->config);
+                       sql_release_socket(inst, handle);
                        RDEBUG("Cannot zap stale entry. No session id in entry.", inst->config->xlat_name);
                        return RLM_MODULE_FAIL;
                }
@@ -1492,15 +1455,15 @@ static int rlm_sql_checksimul(void *instance, REQUEST * request) {
                         *      Failed to check the terminal server for
                         *      duplicate logins: return an error.
                         */
-                       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-                       sql_release_socket(inst, sqlsocket);
+                       (inst->module->sql_finish_select_query)(handle, inst->config);
+                       sql_release_socket(inst, handle);
                        radlog_request(L_ERR, 0, request, "Failed to check the terminal server for user '%s'.", row[2]);
                        return RLM_MODULE_FAIL;
                }
        }
 
-       (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-       sql_release_socket(inst, sqlsocket);
+       (inst->module->sql_finish_select_query)(handle, inst->config);
+       sql_release_socket(inst, handle);
 
        /*
         *      The Auth module apparently looks at request->simul_count,
@@ -1514,8 +1477,8 @@ static int rlm_sql_checksimul(void *instance, REQUEST * request) {
 /*
  *     Postauth: Write a record of the authentication attempt
  */
-static int rlm_sql_postauth(void *instance, REQUEST * request) {
-       SQL_INST *inst = instance;
+static rlm_rcode_t rlm_sql_postauth(void *instance, REQUEST * request) {
+       rlm_sql_t *inst = instance;
        
        if (inst->config->postauth) {
                return acct_redundant(inst, request, inst->config->postauth);