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>
31 #include <freeradius-devel/radiusd.h>
32 #include <freeradius-devel/modules.h>
33 #include <freeradius-devel/modpriv.h>
37 static const char rcsid[] = "$Id$";
40 * Define a structure for our module configuration.
42 typedef struct rlm_sqlippool_t {
43 char *sql_instance_name;
51 /* We ended up removing the init
52 queries so that its up to user
53 to create the db structure and put the required
56 /* Allocation sequence */
57 char *allocate_begin; /* SQL query to begin */
58 char *allocate_clear; /* SQL query to clear an IP */
59 char *allocate_find; /* SQL query to find an unused IP */
60 char *allocate_update; /* SQL query to mark an IP as used */
61 char *allocate_commit; /* SQL query to commit */
62 char *allocate_rollback; /* SQL query to rollback */
65 char *start_begin; /* SQL query to begin */
66 char *start_update; /* SQL query to update an IP entry */
67 char *start_commit; /* SQL query to commit */
68 char *start_rollback; /* SQL query to rollback */
71 char *alive_begin; /* SQL query to begin */
72 char *alive_update; /* SQL query to update an IP entry */
73 char *alive_commit; /* SQL query to commit */
74 char *alive_rollback; /* SQL query to rollback */
77 char *stop_begin; /* SQL query to begin */
78 char *stop_clear; /* SQL query to clear an IP */
79 char *stop_commit; /* SQL query to commit */
80 char *stop_rollback; /* SQL query to rollback */
83 char *on_begin; /* SQL query to begin */
84 char *on_clear; /* SQL query to clear an entire NAS */
85 char *on_commit; /* SQL query to commit */
86 char *on_rollback; /* SQL query to rollback */
89 char *off_begin; /* SQL query to begin */
90 char *off_clear; /* SQL query to clear an entire NAS */
91 char *off_commit; /* SQL query to commit */
92 char *off_rollback; /* SQL query to rollback */
96 char *log_exists; /* There Was an ip address already asigned */
97 char *log_success; /* We successfully allocated ip address from pool */
98 char *log_failed; /* Failed to allocate ip from the pool */
99 char *log_nopool; /* There was no Framed-IP-Address but also no Pool-Name */
101 /* Reserved to handle 255.255.255.254 Requests */
102 char *defaultpool; /* Default Pool-Name if there is non in the check items */
107 * A mapping of configuration file names to internal variables.
109 * Note that the string is dynamically allocated, so it MUST
110 * be freed. When the configuration file parse re-reads the string,
111 * it free's the old one, and strdup's the new one, placing the pointer
112 * to the strdup'd string into 'config.string'. This gets around
115 static CONF_PARSER module_config[] = {
116 {"sql-instance-name",PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,sql_instance_name), NULL, "sql"},
118 { "lease-duration", PW_TYPE_INTEGER, offsetof(rlm_sqlippool_t,lease_duration), NULL, "86400"},
120 { "pool-name" , PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, pool_name), NULL, ""},
122 { "allocate-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_begin), NULL, "BEGIN" },
123 { "allocate-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_clear), NULL, "" },
124 { "allocate-find", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_find), NULL, "" },
125 { "allocate-update", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_update), NULL, "" },
126 { "allocate-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_commit), NULL, "COMMIT" },
127 { "allocate-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_rollback), NULL, "ROLLBACK" },
129 { "start-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_begin), NULL, "BEGIN" },
130 { "start-update", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_update), NULL, "" },
131 { "start-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_commit), NULL, "COMMIT" },
132 { "start-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_rollback), NULL, "ROLLBACK" },
134 { "alive-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_begin), NULL, "BEGIN" },
135 { "alive-update", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_update), NULL, "" },
136 { "alive-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_commit), NULL, "COMMIT" },
137 { "alive-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_rollback), NULL, "ROLLBACK" },
139 { "stop-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_begin), NULL, "BEGIN" },
140 { "stop-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_clear), NULL, "" },
141 { "stop-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_commit), NULL, "COMMIT" },
142 { "stop-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_rollback), NULL, "ROLLBACK" },
144 { "on-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_begin), NULL, "BEGIN" },
145 { "on-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_clear), NULL, "" },
146 { "on-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_commit), NULL, "COMMIT" },
147 { "on-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_rollback), NULL, "ROLLBACK" },
149 { "off-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_begin), NULL, "BEGIN" },
150 { "off-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_clear), NULL, "" },
151 { "off-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_commit), NULL, "COMMIT" },
152 { "off-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_rollback), NULL, "ROLLBACK" },
154 { "sqlippool_log_exists", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_exists), NULL, "" },
155 { "sqlippool_log_success", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_success), NULL, "" },
156 { "sqlippool_log_failed", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_failed), NULL, "" },
157 { "sqlippool_log_nopool", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_nopool), NULL, "" },
159 { "defaultpool", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, defaultpool), NULL, "main_pool" },
163 { NULL, -1, 0, NULL, NULL }
167 * Replace %<whatever> in a string.
174 static int sqlippool_expand(char * out, int outlen, const char * fmt, void * instance, char * param, int param_len)
176 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
179 char tmp[40]; /* For temporary storing of integers */
184 for (p = fmt; *p ; p++) {
188 /* Calculate freespace in output */
189 freespace = outlen - (q - out);
194 if (c != '%' && c != '$' && c != '\\') {
196 * We check if we're inside an open brace. If we are
197 * then we assume this brace is NOT literal, but is
198 * a closing brace and apply it
200 if((c == '}') && openbraces) {
233 case 'P': /* pool name */
234 strNcpy(q, data->pool_name, freespace);
237 case 'I': /* IP address */
238 if (param && param_len > 0) {
239 if (param_len > freespace) {
240 strNcpy(q, param, freespace);
244 memcpy(q, param, param_len);
249 case 'J': /* lease duration */
250 sprintf(tmp, "%d", data->lease_duration);
251 strNcpy(q, tmp, freespace);
264 DEBUG2("sqlippool_expand: '%s'", out);
271 * Query the database executing a command with no result rows
273 static int sqlippool_command(const char * fmt, SQLSOCK * sqlsocket, void * instance, REQUEST * request, char * param, int param_len)
275 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
276 char expansion[MAX_STRING_LEN * 4];
277 char query[MAX_STRING_LEN * 4];
279 sqlippool_expand(expansion, sizeof(expansion), fmt, instance, param, param_len);
282 * Do an xlat on the provided string
285 if (!radius_xlat(query, sizeof(query), expansion, request, NULL)) {
286 radlog(L_ERR, "sqlippool_command: xlat failed.");
291 strcpy(query, expansion);
295 DEBUG2("sqlippool_command: '%s'", query);
297 if (rlm_sql_query(sqlsocket, data->sql_inst, query)){
298 radlog(L_ERR, "sqlippool_command: database query error");
302 (data->sql_inst->module->sql_finish_query)(sqlsocket, data->sql_inst->config);
307 * Query the database expecting a single result row
309 static int sqlippool_query1(char * out, int outlen, const char * fmt, SQLSOCK * sqlsocket, void * instance, REQUEST * request, char * param, int param_len)
311 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
312 char expansion[MAX_STRING_LEN * 4];
313 char query[MAX_STRING_LEN * 4];
317 sqlippool_expand(expansion, sizeof(expansion), fmt, instance, param, param_len);
320 * Do an xlat on the provided string
323 if (!radius_xlat(query, sizeof(query), expansion, request, NULL)) {
324 radlog(L_ERR, "sqlippool_command: xlat failed.");
330 strcpy(query, expansion);
334 DEBUG2("sqlippool_query1: '%s'", query);
336 if (rlm_sql_select_query(sqlsocket, data->sql_inst, query)){
337 radlog(L_ERR, "sqlippool_query1: database query error");
342 r = rlm_sql_fetch_row(sqlsocket, data->sql_inst);
343 (data->sql_inst->module->sql_finish_select_query)(sqlsocket, data->sql_inst->config);
346 DEBUG("sqlippool_query1: SQL query did not succeed");
351 row = sqlsocket->row;
353 DEBUG("sqlippool_query1: SQL query did not return any results");
359 DEBUG("sqlippool_query1: row[0] returned NULL");
366 DEBUG("sqlippool_query1: insufficient string space");
371 strncpy(out, row[0], r);
377 static int sqlippool_initialize_sql(void * instance)
380 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
384 sqlsocket = sql_get_socket(data->sql_inst);
385 if (sqlsocket == NULL) {
386 DEBUG("rlm_sqlippool: cannot allocate sql connection for initialization sequence");
394 * Do any per-module initialization that is separate to each
395 * configured instance of the module. e.g. set up connections
396 * to external databases, read configuration files, set up
397 * dictionary entries, etc.
399 * If configuration information is given in the config section
400 * that must be referenced in later calls, store a handle to it
401 * in *instance otherwise put a null pointer there.
403 static int sqlippool_instantiate(CONF_SECTION * conf, void ** instance)
405 rlm_sqlippool_t * data;
406 char * pool_name = NULL;
409 * Set up a storage area for instance data
411 data = rad_malloc(sizeof(*data));
412 memset(data, 0, sizeof(*data));
415 * If the configuration parameters can't be parsed, then
418 if (cf_section_parse(conf, data, module_config) < 0) {
423 if (data->sql_instance_name == NULL || strlen(data->sql_instance_name) == 0) {
424 radlog(L_ERR, "rlm_sqlippool: the 'sql-instance-name' variable must be set.");
430 * Check that all the queries are in place
433 if (data->allocate_clear == NULL || strlen(data->allocate_clear) == 0) {
434 radlog(L_ERR, "rlm_sqlippool: the 'allocate-clear' statement must be set.");
439 if (data->allocate_find == NULL || strlen(data->allocate_find) == 0) {
440 radlog(L_ERR, "rlm_sqlippool: the 'allocate_find' statement must be set.");
445 if (data->allocate_update == NULL || strlen(data->allocate_update) == 0) {
446 radlog(L_ERR, "rlm_sqlippool: the 'allocate_update' statement must be set.");
451 if (data->start_update == NULL || strlen(data->start_update) == 0) {
452 radlog(L_ERR, "rlm_sqlippool: the 'start-update' statement must be set.");
457 if (data->alive_update == NULL || strlen(data->alive_update) == 0) {
458 radlog(L_ERR, "rlm_sqlippool: the 'alive-update' statement must be set.");
463 if (data->stop_clear == NULL || strlen(data->stop_clear) == 0) {
464 radlog(L_ERR, "rlm_sqlippool: the 'stop-clear' statement must be set.");
469 if (data->on_clear == NULL || strlen(data->on_clear) == 0) {
470 radlog(L_ERR, "rlm_sqlippool: the 'on-clear' statement must be set.");
475 if (data->off_clear == NULL || strlen(data->off_clear) == 0) {
476 radlog(L_ERR, "rlm_sqlippool: the 'off-clear' statement must be set.");
481 pool_name = cf_section_name2(conf);
482 if (pool_name != NULL)
483 data->pool_name = strdup(pool_name);
485 data->pool_name = strdup("ippool");
487 if ( !(data->sql_inst = (SQL_INST *) (find_module_instance(cf_section_find("modules"), data->sql_instance_name))->insthandle) )
489 radlog(L_ERR, "sqlippool_instantiate: failed to find sql instance named %s", data->sql_instance_name);
494 sqlippool_initialize_sql(data);
501 * if we have something to log, then we log it
502 * otherwise we return the retcode as soon as possible
505 static int do_logging(char *str, int retcode)
508 radlog(L_INFO,"%s", str);
514 * Allocate an IP number from the pool.
516 static int sqlippool_postauth(void *instance, REQUEST * request)
518 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
519 char allocation[MAX_STRING_LEN];
521 uint32_t ip_allocation;
524 lrad_ipaddr_t ipaddr;
526 VALUE_PAIR *callingsid;
529 int do_callingsid = 0;
530 int do_calledsid = 0;
532 char logstr[MAX_STRING_LEN];
535 * If there is a Framed-IP-Address attribute in the reply do nothing
537 if (pairfind(request->reply->vps, PW_FRAMED_IP_ADDRESS) != NULL) {
538 /* We already have a Framed-IP-Address */
539 radius_xlat(logstr, sizeof(logstr), data->log_exists, request, NULL);
540 DEBUG("rlm_sqlippool: Framed-IP-Address already exists");
542 return do_logging(logstr, RLM_MODULE_NOOP);
545 if (pairfind(request->config_items, PW_POOL_NAME) == NULL) {
546 DEBUG("rlm_sqlippool: We Dont have Pool-Name in check items.. Lets do nothing..");
547 radius_xlat(logstr, sizeof(logstr), data->log_nopool, request, NULL);
549 return do_logging(logstr, RLM_MODULE_NOOP);
552 if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) {
553 DEBUG("rlm_sqlippool: unknown NAS-IP-Address");
554 return RLM_MODULE_NOOP;
557 if (pairfind(request->packet->vps, PW_NAS_PORT) == NULL) {
558 DEBUG("rlm_sqlippool: unknown NAS-Port");
559 return RLM_MODULE_NOOP;
562 sqlsocket = sql_get_socket(data->sql_inst);
563 if (sqlsocket == NULL) {
564 DEBUG("rlm_sqlippool: cannot allocate sql connection");
565 return RLM_MODULE_NOOP;
571 sqlippool_command(data->allocate_begin, sqlsocket, instance, request,
577 sqlippool_command(data->allocate_clear, sqlsocket, instance, request,
583 allocation_len = sqlippool_query1(allocation, sizeof(allocation),
584 data->allocate_find, sqlsocket, instance, request,
587 if (allocation_len == 0)
592 sqlippool_command(data->allocate_commit, sqlsocket, instance, request,
595 DEBUG("rlm_sqlippool: IP number could not be allocated.");
596 sql_release_socket(data->sql_inst, sqlsocket);
597 radius_xlat(logstr, sizeof(logstr), data->log_failed, request, NULL);
599 return do_logging(logstr, RLM_MODULE_NOOP);
603 /* Reminder to self </tuyan>
604 * please make it work with the ipv6 address'
605 * before the freeradius v2 release
607 if ((ip_hton(allocation, AF_INET, &ipaddr) < 0) ||
608 ((ip_allocation = ipaddr.ipaddr.ip4addr.s_addr) == INADDR_NONE))
613 sqlippool_command(data->allocate_commit, sqlsocket, instance, request,
616 DEBUG("rlm_sqlippool: Invalid IP number [%s] returned from database query.", allocation);
617 sql_release_socket(data->sql_inst, sqlsocket);
618 radius_xlat(logstr, sizeof(logstr), data->log_failed, request, NULL);
620 return do_logging(logstr, RLM_MODULE_NOOP);
626 sqlippool_command(data->allocate_update, sqlsocket, instance, request,
627 allocation, allocation_len);
629 DEBUG("rlm_sqlippool: Allocated IP %s [%08x]", allocation, ip_allocation);
631 if ((vp = paircreate(PW_FRAMED_IP_ADDRESS, PW_TYPE_IPADDR)) == NULL) {
632 radlog(L_ERR|L_CONS, "no memory");
633 sql_release_socket(data->sql_inst, sqlsocket);
634 return RLM_MODULE_NOOP;
636 vp->lvalue = ip_allocation;
637 pairadd(&request->reply->vps, vp);
642 sqlippool_command(data->allocate_commit, sqlsocket, instance, request,
645 sql_release_socket(data->sql_inst, sqlsocket);
646 radius_xlat(logstr, sizeof(logstr), data->log_success, request, NULL);
648 return do_logging(logstr, RLM_MODULE_OK);
651 static int sqlippool_accounting_start(void * instance, REQUEST * request)
653 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
656 if (pairfind(request->packet->vps, PW_NAS_PORT) == NULL) {
657 DEBUG("rlm_ippool: Could not find port number in packet.");
658 return RLM_MODULE_NOOP;
661 if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) {
662 DEBUG("rlm_ippool: Could not find nas information in packet.");
663 return RLM_MODULE_NOOP;
666 sqlsocket = sql_get_socket(data->sql_inst);
667 if (sqlsocket == NULL) {
668 DEBUG("rlm_sqlippool: cannot allocate sql connection");
669 return RLM_MODULE_NOOP;
675 sqlippool_command(data->start_begin, sqlsocket, instance, request,
681 sqlippool_command(data->start_update, sqlsocket, instance, request,
687 sqlippool_command(data->start_commit, sqlsocket, instance, request,
690 sql_release_socket(data->sql_inst, sqlsocket);
692 return RLM_MODULE_OK;
695 static int sqlippool_accounting_alive(void * instance, REQUEST * request)
697 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
700 if (pairfind(request->packet->vps, PW_NAS_PORT) == NULL) {
701 DEBUG("rlm_ippool: Could not find port number in packet.");
702 return RLM_MODULE_NOOP;
705 if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) {
706 DEBUG("rlm_ippool: Could not find nas information in packet.");
707 return RLM_MODULE_NOOP;
710 sqlsocket = sql_get_socket(data->sql_inst);
711 if (sqlsocket == NULL) {
712 DEBUG("rlm_sqlippool: cannot allocate sql connection");
713 return RLM_MODULE_NOOP;
719 sqlippool_command(data->alive_begin, sqlsocket, instance, request,
725 sqlippool_command(data->alive_update, sqlsocket, instance, request,
731 sqlippool_command(data->alive_commit, sqlsocket, instance, request,
734 sql_release_socket(data->sql_inst, sqlsocket);
736 return RLM_MODULE_OK;
739 static int sqlippool_accounting_stop(void * instance, REQUEST * request)
741 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
744 if (pairfind(request->packet->vps, PW_NAS_PORT) == NULL) {
745 DEBUG("rlm_ippool: Could not find port number in packet.");
746 return RLM_MODULE_NOOP;
749 if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) {
750 DEBUG("rlm_ippool: Could not find nas information in packet.");
751 return RLM_MODULE_NOOP;
754 sqlsocket = sql_get_socket(data->sql_inst);
755 if (sqlsocket == NULL) {
756 DEBUG("rlm_sqlippool: cannot allocate sql connection");
757 return RLM_MODULE_NOOP;
763 sqlippool_command(data->stop_begin, sqlsocket, instance, request,
769 sqlippool_command(data->stop_clear, sqlsocket, instance, request,
775 sqlippool_command(data->stop_commit, sqlsocket, instance, request,
778 sql_release_socket(data->sql_inst, sqlsocket);
780 return RLM_MODULE_OK;
783 static int sqlippool_accounting_on(void * instance, REQUEST * request)
785 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
788 if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) {
789 DEBUG("rlm_ippool: Could not find nas information in packet.");
790 return RLM_MODULE_NOOP;
793 sqlsocket = sql_get_socket(data->sql_inst);
794 if (sqlsocket == NULL) {
795 DEBUG("rlm_sqlippool: cannot allocate sql connection");
796 return RLM_MODULE_NOOP;
802 sqlippool_command(data->on_begin, sqlsocket, instance, request,
808 sqlippool_command(data->on_clear, sqlsocket, instance, request,
814 sqlippool_command(data->on_commit, sqlsocket, instance, request,
817 sql_release_socket(data->sql_inst, sqlsocket);
819 return RLM_MODULE_OK;
822 static int sqlippool_accounting_off(void * instance, REQUEST * request)
824 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
827 if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) {
828 DEBUG("rlm_ippool: Could not find nas information in packet.");
829 return RLM_MODULE_NOOP;
832 sqlsocket = sql_get_socket(data->sql_inst);
833 if (sqlsocket == NULL) {
834 DEBUG("rlm_sqlippool: cannot allocate sql connection");
835 return RLM_MODULE_NOOP;
841 sqlippool_command(data->off_begin, sqlsocket, instance, request,
847 sqlippool_command(data->off_clear, sqlsocket, instance, request,
853 sqlippool_command(data->off_commit, sqlsocket, instance, request,
856 sql_release_socket(data->sql_inst, sqlsocket);
858 return RLM_MODULE_OK;
862 * Check for an Accounting-Stop
863 * If we find one and we have allocated an IP to this nas/port combination, deallocate it.
865 static int sqlippool_accounting(void * instance, REQUEST * request)
868 int acct_status_type;
870 vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE);
872 DEBUG("rlm_sqlippool: Could not find account status type in packet.");
873 return RLM_MODULE_NOOP;
875 acct_status_type = vp->lvalue;
877 switch (acct_status_type) {
878 case PW_STATUS_START:
879 return sqlippool_accounting_start(instance, request);
881 case PW_STATUS_ALIVE:
882 return sqlippool_accounting_alive(instance, request);
885 return sqlippool_accounting_stop(instance, request);
887 case PW_STATUS_ACCOUNTING_ON:
888 return sqlippool_accounting_on(instance, request);
890 case PW_STATUS_ACCOUNTING_OFF:
891 return sqlippool_accounting_off(instance, request);
894 /* We don't care about any other accounting packet */
895 return RLM_MODULE_NOOP;
899 static int sqlippool_detach(void *instance)
901 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
903 free(data->sql_instance_name);
904 free(data->pool_name);
908 free(data->allocate_begin);
909 free(data->allocate_clear);
910 free(data->allocate_find);
911 free(data->allocate_update);
912 free(data->allocate_commit);
913 free(data->allocate_rollback);
915 free(data->start_begin);
916 free(data->start_update);
917 free(data->start_commit);
918 free(data->start_rollback);
920 free(data->alive_begin);
921 free(data->alive_update);
922 free(data->alive_commit);
923 free(data->alive_rollback);
925 free(data->stop_begin);
926 free(data->stop_clear);
927 free(data->stop_commit);
928 free(data->stop_rollback);
930 free(data->on_begin);
931 free(data->on_clear);
932 free(data->on_commit);
933 free(data->on_rollback);
935 free(data->off_begin);
936 free(data->off_clear);
937 free(data->off_commit);
938 free(data->off_rollback);
940 free(data->log_exists);
941 free(data->log_failed);
942 free(data->log_nopool);
943 free(data->log_success);
944 free(data->defaultpool);
952 * The module name should be the only globally exported symbol.
953 * That is, everything else should be 'static'.
955 * If the module needs to temporarily modify it's instantiation
956 * data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
957 * The server will then take care of ensuring that the module
958 * is single-threaded.
960 module_t rlm_sqlippool = {
963 RLM_TYPE_THREAD_SAFE, /* type */
964 sqlippool_instantiate, /* instantiation */
965 sqlippool_detach, /* detach */
967 NULL, /* authentication */
968 NULL, /* authorization */
969 NULL, /* preaccounting */
970 sqlippool_accounting, /* accounting */
971 NULL, /* checksimul */
972 NULL, /* pre-proxy */
973 NULL, /* post-proxy */
974 sqlippool_postauth /* post-auth */