2 * rlm_sqlippool.c rlm_sqlippool - FreeRADIUS SQL IP Pool Module
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Copyright 2002 Globe.Net Communications Limited
21 * Copyright 2006 The FreeRADIUS server project
22 * Copyright 2006 Suntel Communications
25 #include <freeradius-devel/autoconf.h>
26 #include <freeradius-devel/libradius.h>
32 #include <netinet/in.h>
34 #include <freeradius-devel/radiusd.h>
35 #include <freeradius-devel/modules.h>
36 #include <freeradius-devel/conffile.h>
37 #include <freeradius-devel/modpriv.h>
41 static const char rcsid[] = "$Id$";
44 * Define a structure for our module configuration.
46 typedef struct rlm_sqlippool_t {
47 char *sql_instance_name;
55 /* We ended up removing the init
56 queries so that its up to user
57 to create the db structure and put the required
60 /* Allocation sequence */
61 char *allocate_begin; /* SQL query to begin */
62 char *allocate_clear; /* SQL query to clear an IP */
63 char *allocate_find; /* SQL query to find an unused IP */
64 char *allocate_update; /* SQL query to mark an IP as used */
65 char *allocate_commit; /* SQL query to commit */
66 char *allocate_rollback; /* SQL query to rollback */
69 char *start_begin; /* SQL query to begin */
70 char *start_update; /* SQL query to update an IP entry */
71 char *start_commit; /* SQL query to commit */
72 char *start_rollback; /* SQL query to rollback */
75 char *alive_begin; /* SQL query to begin */
76 char *alive_update; /* SQL query to update an IP entry */
77 char *alive_commit; /* SQL query to commit */
78 char *alive_rollback; /* SQL query to rollback */
81 char *stop_begin; /* SQL query to begin */
82 char *stop_clear; /* SQL query to clear an IP */
83 char *stop_commit; /* SQL query to commit */
84 char *stop_rollback; /* SQL query to rollback */
87 char *on_begin; /* SQL query to begin */
88 char *on_clear; /* SQL query to clear an entire NAS */
89 char *on_commit; /* SQL query to commit */
90 char *on_rollback; /* SQL query to rollback */
93 char *off_begin; /* SQL query to begin */
94 char *off_clear; /* SQL query to clear an entire NAS */
95 char *off_commit; /* SQL query to commit */
96 char *off_rollback; /* SQL query to rollback */
101 * A mapping of configuration file names to internal variables.
103 * Note that the string is dynamically allocated, so it MUST
104 * be freed. When the configuration file parse re-reads the string,
105 * it free's the old one, and strdup's the new one, placing the pointer
106 * to the strdup'd string into 'config.string'. This gets around
109 static CONF_PARSER module_config[] = {
110 {"sql-instance-name",PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,sql_instance_name), NULL, "sql"},
112 { "lease-duration", PW_TYPE_INTEGER, offsetof(rlm_sqlippool_t,lease_duration), NULL, "86400"},
114 { "pool-name" , PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, pool_name), NULL, ""},
116 { "allocate-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_begin), NULL, "BEGIN" },
117 { "allocate-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_clear), NULL, "" },
118 { "allocate-find", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_find), NULL, "" },
119 { "allocate-update", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_update), NULL, "" },
120 { "allocate-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_commit), NULL, "COMMIT" },
121 { "allocate-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_rollback), NULL, "ROLLBACK" },
123 { "start-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_begin), NULL, "BEGIN" },
124 { "start-update", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_update), NULL, "" },
125 { "start-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_commit), NULL, "COMMIT" },
126 { "start-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_rollback), NULL, "ROLLBACK" },
128 { "alive-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_begin), NULL, "BEGIN" },
129 { "alive-update", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_update), NULL, "" },
130 { "alive-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_commit), NULL, "COMMIT" },
131 { "alive-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_rollback), NULL, "ROLLBACK" },
133 { "stop-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_begin), NULL, "BEGIN" },
134 { "stop-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_clear), NULL, "" },
135 { "stop-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_commit), NULL, "COMMIT" },
136 { "stop-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_rollback), NULL, "ROLLBACK" },
138 { "on-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_begin), NULL, "BEGIN" },
139 { "on-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_clear), NULL, "" },
140 { "on-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_commit), NULL, "COMMIT" },
141 { "on-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_rollback), NULL, "ROLLBACK" },
143 { "off-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_begin), NULL, "BEGIN" },
144 { "off-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_clear), NULL, "" },
145 { "off-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_commit), NULL, "COMMIT" },
146 { "off-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_rollback), NULL, "ROLLBACK" },
148 { NULL, -1, 0, NULL, NULL }
152 * Replace %<whatever> in a string.
159 static int sqlippool_expand(char * out, int outlen, const char * fmt, void * instance, char * param, int param_len)
161 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
164 char tmp[40]; /* For temporary storing of integers */
169 for (p = fmt; *p ; p++) {
173 /* Calculate freespace in output */
174 freespace = outlen - (q - out);
179 if (c != '%' && c != '$' && c != '\\') {
181 * We check if we're inside an open brace. If we are
182 * then we assume this brace is NOT literal, but is
183 * a closing brace and apply it
185 if((c == '}') && openbraces) {
218 case 'P': /* pool name */
219 strNcpy(q, data->pool_name, freespace);
222 case 'I': /* IP address */
223 if (param && param_len > 0) {
224 if (param_len > freespace) {
225 strNcpy(q, param, freespace);
229 memcpy(q, param, param_len);
234 case 'J': /* lease duration */
235 sprintf(tmp, "%d", data->lease_duration);
236 strNcpy(q, tmp, freespace);
249 DEBUG2("sqlippool_expand: '%s'", out);
256 * Query the database executing a command with no result rows
258 static int sqlippool_command(const char * fmt, SQLSOCK * sqlsocket, void * instance, REQUEST * request, char * param, int param_len)
260 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
261 char expansion[MAX_STRING_LEN * 4];
262 char query[MAX_STRING_LEN * 4];
264 sqlippool_expand(expansion, sizeof(expansion), fmt, instance, param, param_len);
267 * Do an xlat on the provided string
270 if (!radius_xlat(query, sizeof(query), expansion, request, NULL)) {
271 radlog(L_ERR, "sqlippool_command: xlat failed.");
276 strcpy(query, expansion);
280 DEBUG2("sqlippool_command: '%s'", query);
282 if (rlm_sql_query(sqlsocket, data->sql_inst, query)){
283 radlog(L_ERR, "sqlippool_command: database query error");
287 (data->sql_inst->module->sql_finish_query)(sqlsocket, data->sql_inst->config);
292 * Query the database expecting a single result row
294 static int sqlippool_query1(char * out, int outlen, const char * fmt, SQLSOCK * sqlsocket, void * instance, REQUEST * request, char * param, int param_len)
296 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
297 char expansion[MAX_STRING_LEN * 4];
298 char query[MAX_STRING_LEN * 4];
302 sqlippool_expand(expansion, sizeof(expansion), fmt, instance, param, param_len);
305 * Do an xlat on the provided string
308 if (!radius_xlat(query, sizeof(query), expansion, request, NULL)) {
309 radlog(L_ERR, "sqlippool_command: xlat failed.");
315 strcpy(query, expansion);
319 DEBUG2("sqlippool_query1: '%s'", query);
321 if (rlm_sql_select_query(sqlsocket, data->sql_inst, query)){
322 radlog(L_ERR, "sqlippool_query1: database query error");
327 r = rlm_sql_fetch_row(sqlsocket, data->sql_inst);
328 (data->sql_inst->module->sql_finish_select_query)(sqlsocket, data->sql_inst->config);
331 DEBUG("sqlippool_query1: SQL query did not succeed");
336 row = sqlsocket->row;
338 DEBUG("sqlippool_query1: SQL query did not return any results");
344 DEBUG("sqlippool_query1: row[0] returned NULL");
351 DEBUG("sqlippool_query1: insufficient string space");
356 strncpy(out, row[0], r);
362 static int sqlippool_initialize_sql(void * instance)
365 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
369 sqlsocket = sql_get_socket(data->sql_inst);
370 if (sqlsocket == NULL) {
371 DEBUG("rlm_sqlippool: cannot allocate sql connection for initialization sequence");
379 * Do any per-module initialization that is separate to each
380 * configured instance of the module. e.g. set up connections
381 * to external databases, read configuration files, set up
382 * dictionary entries, etc.
384 * If configuration information is given in the config section
385 * that must be referenced in later calls, store a handle to it
386 * in *instance otherwise put a null pointer there.
388 static int sqlippool_instantiate(CONF_SECTION * conf, void ** instance)
390 rlm_sqlippool_t * data;
391 char * pool_name = NULL;
394 * Set up a storage area for instance data
396 data = rad_malloc(sizeof(*data));
397 memset(data, 0, sizeof(*data));
400 * If the configuration parameters can't be parsed, then
403 if (cf_section_parse(conf, data, module_config) < 0) {
408 if (data->sql_instance_name == NULL || strlen(data->sql_instance_name) == 0) {
409 radlog(L_ERR, "rlm_sqlippool: the 'sql-instance-name' variable must be set.");
415 * Check that all the queries are in place
418 if (data->allocate_clear == NULL || strlen(data->allocate_clear) == 0) {
419 radlog(L_ERR, "rlm_sqlippool: the 'allocate-clear' statement must be set.");
424 if (data->allocate_find == NULL || strlen(data->allocate_find) == 0) {
425 radlog(L_ERR, "rlm_sqlippool: the 'allocate_find' statement must be set.");
430 if (data->allocate_update == NULL || strlen(data->allocate_update) == 0) {
431 radlog(L_ERR, "rlm_sqlippool: the 'allocate_update' statement must be set.");
436 if (data->start_update == NULL || strlen(data->start_update) == 0) {
437 radlog(L_ERR, "rlm_sqlippool: the 'start-update' statement must be set.");
442 if (data->alive_update == NULL || strlen(data->alive_update) == 0) {
443 radlog(L_ERR, "rlm_sqlippool: the 'alive-update' statement must be set.");
448 if (data->stop_clear == NULL || strlen(data->stop_clear) == 0) {
449 radlog(L_ERR, "rlm_sqlippool: the 'stop-clear' statement must be set.");
454 if (data->on_clear == NULL || strlen(data->on_clear) == 0) {
455 radlog(L_ERR, "rlm_sqlippool: the 'on-clear' statement must be set.");
460 if (data->off_clear == NULL || strlen(data->off_clear) == 0) {
461 radlog(L_ERR, "rlm_sqlippool: the 'off-clear' statement must be set.");
466 pool_name = cf_section_name2(conf);
467 if (pool_name != NULL)
468 data->pool_name = strdup(pool_name);
470 data->pool_name = strdup("ippool");
472 if ( !(data->sql_inst = (SQL_INST *) (find_module_instance(cf_section_find("modules"), data->sql_instance_name))->insthandle) )
474 radlog(L_ERR, "sqlippool_instantiate: failed to find sql instance named %s", data->sql_instance_name);
479 sqlippool_initialize_sql(data);
485 * Allocate an IP number from the pool.
487 static int sqlippool_postauth(void *instance, REQUEST * request)
489 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
490 char allocation[MAX_STRING_LEN];
492 uint32_t ip_allocation;
495 lrad_ipaddr_t ipaddr;
497 VALUE_PAIR *callingsid;
499 VALUE_PAIR *framedip;
502 int do_callingsid = 0;
503 int do_calledsid = 0;
506 char logstr[MAX_STRING_LEN];
507 char ip[MAX_STRING_LEN];
511 if ((pair = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) != NULL)
514 if ((pair = pairfind(request->packet->vps, PW_CALLED_STATION_ID)) != NULL)
517 if ((pair = pairfind(request->packet->vps, PW_USER_NAME)) != NULL)
520 if (do_calledsid && do_callingsid && do_username){
521 radius_xlat(logstr, sizeof(logstr), "[ [%{User-Name}] Pool %{check:Pool-Name} cli %{Calling-Station-Id} did %{Called-Station-Id})]", request, NULL);
523 memset(logstr, '\0', sizeof(logstr));
527 * If there is a Framed-IP-Address attribute in the reply do nothing
529 if ((framedip = pairfind(request->reply->vps, PW_FRAMED_IP_ADDRESS)) != NULL) {
530 ip_ntoa(ip, framedip->lvalue);
531 radlog(L_INFO,"rlm_sqlippool: Existing ip [%s] For %s", ip, logstr);
532 DEBUG("rlm_sqlippool: Framed-IP-Address already exists");
533 return RLM_MODULE_NOOP;
536 if (pairfind(request->config_items, PW_POOL_NAME) == NULL) {
537 DEBUG("rlm_sqlippool: We Dont have Pool-Name in check items.. Lets do nothing..");
538 radlog(L_INFO, "rlm_sqlippool: Missing Pool-Name for %s", logstr);
539 return RLM_MODULE_NOOP;
543 if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) {
544 DEBUG("rlm_sqlippool: unknown NAS-IP-Address");
545 return RLM_MODULE_NOOP;
548 if (pairfind(request->packet->vps, PW_NAS_PORT) == NULL) {
549 DEBUG("rlm_sqlippool: unknown NAS-Port");
550 return RLM_MODULE_NOOP;
553 sqlsocket = sql_get_socket(data->sql_inst);
554 if (sqlsocket == NULL) {
555 DEBUG("rlm_sqlippool: cannot allocate sql connection");
556 return RLM_MODULE_NOOP;
562 sqlippool_command(data->allocate_begin, sqlsocket, instance, request,
568 sqlippool_command(data->allocate_clear, sqlsocket, instance, request,
574 allocation_len = sqlippool_query1(allocation, sizeof(allocation),
575 data->allocate_find, sqlsocket, instance, request,
580 radlog(L_INFO,"rlm_sqlippool: ip [%s] %s", allocation, logstr);
582 if (allocation_len == 0)
587 sqlippool_command(data->allocate_commit, sqlsocket, instance, request,
590 DEBUG("rlm_sqlippool: IP number could not be allocated.");
591 sql_release_socket(data->sql_inst, sqlsocket);
592 return RLM_MODULE_NOOP;
596 if ((ip_hton(allocation, AF_INET, &ipaddr) < 0) ||
597 ((ip_allocation = ipaddr.ipaddr.ip4addr.s_addr) == INADDR_NONE))
602 sqlippool_command(data->allocate_commit, sqlsocket, instance, request,
605 DEBUG("rlm_sqlippool: Invalid IP number [%s] returned from database query.", allocation);
606 sql_release_socket(data->sql_inst, sqlsocket);
607 return RLM_MODULE_NOOP;
613 sqlippool_command(data->allocate_update, sqlsocket, instance, request,
614 allocation, allocation_len);
616 DEBUG("rlm_sqlippool: Allocated IP %s [%08x]", allocation, ip_allocation);
618 if ((vp = paircreate(PW_FRAMED_IP_ADDRESS, PW_TYPE_IPADDR)) == NULL) {
619 radlog(L_ERR|L_CONS, "no memory");
620 sql_release_socket(data->sql_inst, sqlsocket);
621 return RLM_MODULE_NOOP;
623 vp->lvalue = ip_allocation;
624 pairadd(&request->reply->vps, vp);
629 sqlippool_command(data->allocate_commit, sqlsocket, instance, request,
632 sql_release_socket(data->sql_inst, sqlsocket);
633 return RLM_MODULE_OK;
636 static int sqlippool_accounting_start(void * instance, REQUEST * request)
638 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
641 if (pairfind(request->packet->vps, PW_NAS_PORT) == NULL) {
642 DEBUG("rlm_ippool: Could not find port number in packet.");
643 return RLM_MODULE_NOOP;
646 if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) {
647 DEBUG("rlm_ippool: Could not find nas information in packet.");
648 return RLM_MODULE_NOOP;
651 sqlsocket = sql_get_socket(data->sql_inst);
652 if (sqlsocket == NULL) {
653 DEBUG("rlm_sqlippool: cannot allocate sql connection");
654 return RLM_MODULE_NOOP;
660 sqlippool_command(data->start_begin, sqlsocket, instance, request,
666 sqlippool_command(data->start_update, sqlsocket, instance, request,
672 sqlippool_command(data->start_commit, sqlsocket, instance, request,
675 sql_release_socket(data->sql_inst, sqlsocket);
677 return RLM_MODULE_OK;
680 static int sqlippool_accounting_alive(void * instance, REQUEST * request)
682 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
685 if (pairfind(request->packet->vps, PW_NAS_PORT) == NULL) {
686 DEBUG("rlm_ippool: Could not find port number in packet.");
687 return RLM_MODULE_NOOP;
690 if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) {
691 DEBUG("rlm_ippool: Could not find nas information in packet.");
692 return RLM_MODULE_NOOP;
695 sqlsocket = sql_get_socket(data->sql_inst);
696 if (sqlsocket == NULL) {
697 DEBUG("rlm_sqlippool: cannot allocate sql connection");
698 return RLM_MODULE_NOOP;
704 sqlippool_command(data->alive_begin, sqlsocket, instance, request,
710 sqlippool_command(data->alive_update, sqlsocket, instance, request,
716 sqlippool_command(data->alive_commit, sqlsocket, instance, request,
719 sql_release_socket(data->sql_inst, sqlsocket);
721 return RLM_MODULE_OK;
724 static int sqlippool_accounting_stop(void * instance, REQUEST * request)
726 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
729 if (pairfind(request->packet->vps, PW_NAS_PORT) == NULL) {
730 DEBUG("rlm_ippool: Could not find port number in packet.");
731 return RLM_MODULE_NOOP;
734 if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) {
735 DEBUG("rlm_ippool: Could not find nas information in packet.");
736 return RLM_MODULE_NOOP;
739 sqlsocket = sql_get_socket(data->sql_inst);
740 if (sqlsocket == NULL) {
741 DEBUG("rlm_sqlippool: cannot allocate sql connection");
742 return RLM_MODULE_NOOP;
748 sqlippool_command(data->stop_begin, sqlsocket, instance, request,
754 sqlippool_command(data->stop_clear, sqlsocket, instance, request,
760 sqlippool_command(data->stop_commit, sqlsocket, instance, request,
763 sql_release_socket(data->sql_inst, sqlsocket);
765 return RLM_MODULE_OK;
768 static int sqlippool_accounting_on(void * instance, REQUEST * request)
770 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
773 if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) {
774 DEBUG("rlm_ippool: Could not find nas information in packet.");
775 return RLM_MODULE_NOOP;
778 sqlsocket = sql_get_socket(data->sql_inst);
779 if (sqlsocket == NULL) {
780 DEBUG("rlm_sqlippool: cannot allocate sql connection");
781 return RLM_MODULE_NOOP;
787 sqlippool_command(data->on_begin, sqlsocket, instance, request,
793 sqlippool_command(data->on_clear, sqlsocket, instance, request,
799 sqlippool_command(data->on_commit, sqlsocket, instance, request,
802 sql_release_socket(data->sql_inst, sqlsocket);
804 return RLM_MODULE_OK;
807 static int sqlippool_accounting_off(void * instance, REQUEST * request)
809 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
812 if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) {
813 DEBUG("rlm_ippool: Could not find nas information in packet.");
814 return RLM_MODULE_NOOP;
817 sqlsocket = sql_get_socket(data->sql_inst);
818 if (sqlsocket == NULL) {
819 DEBUG("rlm_sqlippool: cannot allocate sql connection");
820 return RLM_MODULE_NOOP;
826 sqlippool_command(data->off_begin, sqlsocket, instance, request,
832 sqlippool_command(data->off_clear, sqlsocket, instance, request,
838 sqlippool_command(data->off_commit, sqlsocket, instance, request,
841 sql_release_socket(data->sql_inst, sqlsocket);
843 return RLM_MODULE_OK;
847 * Check for an Accounting-Stop
848 * If we find one and we have allocated an IP to this nas/port combination, deallocate it.
850 static int sqlippool_accounting(void * instance, REQUEST * request)
853 int acct_status_type;
855 vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE);
857 DEBUG("rlm_sqlippool: Could not find account status type in packet.");
858 return RLM_MODULE_NOOP;
860 acct_status_type = vp->lvalue;
862 switch (acct_status_type) {
863 case PW_STATUS_START:
864 return sqlippool_accounting_start(instance, request);
866 case PW_STATUS_ALIVE:
867 return sqlippool_accounting_alive(instance, request);
870 return sqlippool_accounting_stop(instance, request);
872 case PW_STATUS_ACCOUNTING_ON:
873 return sqlippool_accounting_on(instance, request);
875 case PW_STATUS_ACCOUNTING_OFF:
876 return sqlippool_accounting_off(instance, request);
879 /* We don't care about any other accounting packet */
880 return RLM_MODULE_NOOP;
884 static int sqlippool_detach(void *instance)
886 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
888 free(data->sql_instance_name);
889 free(data->pool_name);
891 free(data->allocate_begin);
892 free(data->allocate_clear);
893 free(data->allocate_find);
894 free(data->allocate_update);
895 free(data->allocate_commit);
896 free(data->allocate_rollback);
898 free(data->start_begin);
899 free(data->start_update);
900 free(data->start_commit);
901 free(data->start_rollback);
903 free(data->alive_begin);
904 free(data->alive_update);
905 free(data->alive_commit);
906 free(data->alive_rollback);
908 free(data->stop_begin);
909 free(data->stop_clear);
910 free(data->stop_commit);
911 free(data->stop_rollback);
913 free(data->on_begin);
914 free(data->on_clear);
915 free(data->on_commit);
916 free(data->on_rollback);
918 free(data->off_begin);
919 free(data->off_clear);
920 free(data->off_commit);
921 free(data->off_rollback);
927 * The module name should be the only globally exported symbol.
928 * That is, everything else should be 'static'.
930 * If the module needs to temporarily modify it's instantiation
931 * data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
932 * The server will then take care of ensuring that the module
933 * is single-threaded.
935 module_t rlm_sqlippool = {
938 RLM_TYPE_THREAD_SAFE, /* type */
939 sqlippool_instantiate, /* instantiation */
940 sqlippool_detach, /* detach */
942 NULL, /* authentication */
943 NULL, /* authorization */
944 NULL, /* preaccounting */
945 sqlippool_accounting, /* accounting */
946 NULL, /* checksimul */
947 NULL, /* pre-proxy */
948 NULL, /* post-proxy */
949 sqlippool_postauth /* post-auth */