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/ident.h>
28 #include <freeradius-devel/radiusd.h>
35 * Define a structure for our module configuration.
37 typedef struct rlm_sqlippool_t {
38 char *sql_instance_name;
46 /* We ended up removing the init
47 queries so that its up to user
48 to create the db structure and put the required
51 /* Allocation sequence */
52 char *allocate_begin; /* SQL query to begin */
53 char *allocate_clear; /* SQL query to clear an IP */
54 char *allocate_find; /* SQL query to find an unused IP */
55 char *allocate_update; /* SQL query to mark an IP as used */
56 char *allocate_commit; /* SQL query to commit */
57 char *allocate_rollback; /* SQL query to rollback */
59 char *pool_check; /* Query to check for the existence of the pool */
62 char *start_begin; /* SQL query to begin */
63 char *start_update; /* SQL query to update an IP entry */
64 char *start_commit; /* SQL query to commit */
65 char *start_rollback; /* SQL query to rollback */
68 char *alive_begin; /* SQL query to begin */
69 char *alive_update; /* SQL query to update an IP entry */
70 char *alive_commit; /* SQL query to commit */
71 char *alive_rollback; /* SQL query to rollback */
74 char *stop_begin; /* SQL query to begin */
75 char *stop_clear; /* SQL query to clear an IP */
76 char *stop_commit; /* SQL query to commit */
77 char *stop_rollback; /* SQL query to rollback */
80 char *on_begin; /* SQL query to begin */
81 char *on_clear; /* SQL query to clear an entire NAS */
82 char *on_commit; /* SQL query to commit */
83 char *on_rollback; /* SQL query to rollback */
86 char *off_begin; /* SQL query to begin */
87 char *off_clear; /* SQL query to clear an entire NAS */
88 char *off_commit; /* SQL query to commit */
89 char *off_rollback; /* SQL query to rollback */
92 char *log_exists; /* There was an ip address already assigned */
93 char *log_success; /* We successfully allocated ip address from pool */
94 char *log_clear; /* We successfully deallocated ip address from pool */
95 char *log_failed; /* Failed to allocate ip from the pool */
96 char *log_nopool; /* There was no Framed-IP-Address but also no Pool-Name */
98 /* Reserved to handle 255.255.255.254 Requests */
99 char *defaultpool; /* Default Pool-Name if there is none in the check items */
104 * A mapping of configuration file names to internal variables.
106 * Note that the string is dynamically allocated, so it MUST
107 * be freed. When the configuration file parse re-reads the string,
108 * it free's the old one, and strdup's the new one, placing the pointer
109 * to the strdup'd string into 'config.string'. This gets around
112 static CONF_PARSER module_config[] = {
113 {"sql-instance-name",PW_TYPE_STRING_PTR,
114 offsetof(rlm_sqlippool_t,sql_instance_name), NULL, "sql"},
116 { "lease-duration", PW_TYPE_INTEGER,
117 offsetof(rlm_sqlippool_t,lease_duration), NULL, "86400"},
119 { "pool-name" , PW_TYPE_STRING_PTR,
120 offsetof(rlm_sqlippool_t, pool_name), NULL, ""},
122 { "allocate-begin", PW_TYPE_STRING_PTR,
123 offsetof(rlm_sqlippool_t,allocate_begin), NULL, "START TRANSACTION" },
124 { "allocate-clear", PW_TYPE_STRING_PTR,
125 offsetof(rlm_sqlippool_t,allocate_clear), NULL, "" },
126 { "allocate-find", PW_TYPE_STRING_PTR,
127 offsetof(rlm_sqlippool_t,allocate_find), NULL, "" },
128 { "allocate-update", PW_TYPE_STRING_PTR,
129 offsetof(rlm_sqlippool_t,allocate_update), NULL, "" },
130 { "allocate-commit", PW_TYPE_STRING_PTR,
131 offsetof(rlm_sqlippool_t,allocate_commit), NULL, "COMMIT" },
132 { "allocate-rollback", PW_TYPE_STRING_PTR,
133 offsetof(rlm_sqlippool_t,allocate_rollback), NULL, "ROLLBACK" },
135 { "pool-check", PW_TYPE_STRING_PTR,
136 offsetof(rlm_sqlippool_t,pool_check), NULL, "" },
138 { "start-begin", PW_TYPE_STRING_PTR,
139 offsetof(rlm_sqlippool_t,start_begin), NULL, "START TRANSACTION" },
140 { "start-update", PW_TYPE_STRING_PTR,
141 offsetof(rlm_sqlippool_t,start_update), NULL, "" },
142 { "start-commit", PW_TYPE_STRING_PTR,
143 offsetof(rlm_sqlippool_t,start_commit), NULL, "COMMIT" },
144 { "start-rollback", PW_TYPE_STRING_PTR,
145 offsetof(rlm_sqlippool_t,start_rollback), NULL, "ROLLBACK" },
147 { "alive-begin", PW_TYPE_STRING_PTR,
148 offsetof(rlm_sqlippool_t,alive_begin), NULL, "START TRANSACTION" },
149 { "alive-update", PW_TYPE_STRING_PTR,
150 offsetof(rlm_sqlippool_t,alive_update), NULL, "" },
151 { "alive-commit", PW_TYPE_STRING_PTR,
152 offsetof(rlm_sqlippool_t,alive_commit), NULL, "COMMIT" },
153 { "alive-rollback", PW_TYPE_STRING_PTR,
154 offsetof(rlm_sqlippool_t,alive_rollback), NULL, "ROLLBACK" },
156 { "stop-begin", PW_TYPE_STRING_PTR,
157 offsetof(rlm_sqlippool_t,stop_begin), NULL, "START TRANSACTION" },
158 { "stop-clear", PW_TYPE_STRING_PTR,
159 offsetof(rlm_sqlippool_t,stop_clear), NULL, "" },
160 { "stop-commit", PW_TYPE_STRING_PTR,
161 offsetof(rlm_sqlippool_t,stop_commit), NULL, "COMMIT" },
162 { "stop-rollback", PW_TYPE_STRING_PTR,
163 offsetof(rlm_sqlippool_t,stop_rollback), NULL, "ROLLBACK" },
165 { "on-begin", PW_TYPE_STRING_PTR,
166 offsetof(rlm_sqlippool_t,on_begin), NULL, "START TRANSACTION" },
167 { "on-clear", PW_TYPE_STRING_PTR,
168 offsetof(rlm_sqlippool_t,on_clear), NULL, "" },
169 { "on-commit", PW_TYPE_STRING_PTR,
170 offsetof(rlm_sqlippool_t,on_commit), NULL, "COMMIT" },
171 { "on-rollback", PW_TYPE_STRING_PTR,
172 offsetof(rlm_sqlippool_t,on_rollback), NULL, "ROLLBACK" },
174 { "off-begin", PW_TYPE_STRING_PTR,
175 offsetof(rlm_sqlippool_t,off_begin), NULL, "START TRANSACTION" },
176 { "off-clear", PW_TYPE_STRING_PTR,
177 offsetof(rlm_sqlippool_t,off_clear), NULL, "" },
178 { "off-commit", PW_TYPE_STRING_PTR,
179 offsetof(rlm_sqlippool_t,off_commit), NULL, "COMMIT" },
180 { "off-rollback", PW_TYPE_STRING_PTR,
181 offsetof(rlm_sqlippool_t,off_rollback), NULL, "ROLLBACK" },
183 { "sqlippool_log_exists", PW_TYPE_STRING_PTR,
184 offsetof(rlm_sqlippool_t, log_exists), NULL, "" },
185 { "sqlippool_log_success", PW_TYPE_STRING_PTR,
186 offsetof(rlm_sqlippool_t, log_success), NULL, "" },
187 { "sqlippool_log_clear", PW_TYPE_STRING_PTR,
188 offsetof(rlm_sqlippool_t, log_clear), NULL, "" },
189 { "sqlippool_log_failed", PW_TYPE_STRING_PTR,
190 offsetof(rlm_sqlippool_t, log_failed), NULL, "" },
191 { "sqlippool_log_nopool", PW_TYPE_STRING_PTR,
192 offsetof(rlm_sqlippool_t, log_nopool), NULL, "" },
194 { "defaultpool", PW_TYPE_STRING_PTR,
195 offsetof(rlm_sqlippool_t, defaultpool), NULL, "main_pool" },
197 { NULL, -1, 0, NULL, NULL }
201 * Replace %<whatever> in a string.
208 static int sqlippool_expand(char * out, int outlen, const char * fmt,
209 rlm_sqlippool_t *data, char * param, int param_len)
213 char tmp[40]; /* For temporary storing of integers */
216 for (p = fmt; *p ; p++) {
220 /* Calculate freespace in output */
221 freespace = outlen - (q - out);
226 if (c != '%' && c != '$' && c != '\\') {
256 case 'P': /* pool name */
257 strlcpy(q, data->pool_name, freespace);
260 case 'I': /* IP address */
261 if (param && param_len > 0) {
262 if (param_len > freespace) {
263 strlcpy(q, param, freespace);
267 memcpy(q, param, param_len);
272 case 'J': /* lease duration */
273 sprintf(tmp, "%d", data->lease_duration);
274 strlcpy(q, tmp, freespace);
287 DEBUG2("sqlippool_expand: '%s'", out);
294 * Query the database executing a command with no result rows
296 static int sqlippool_command(const char * fmt, SQLSOCK * sqlsocket,
297 rlm_sqlippool_t *data, REQUEST * request,
298 char * param, int param_len)
300 char expansion[MAX_STRING_LEN * 4];
301 char query[MAX_STRING_LEN * 4];
303 sqlippool_expand(expansion, sizeof(expansion),
304 fmt, data, param, param_len);
307 * Do an xlat on the provided string
310 if (!radius_xlat(query, sizeof(query), expansion, request, data->sql_inst->sql_escape_func)) {
311 radlog(L_ERR, "sqlippool_command: xlat failed on: '%s'", query);
315 strcpy(query, expansion);
319 DEBUG2("sqlippool_command: '%s'", query);
321 if (data->sql_inst->sql_query(sqlsocket, data->sql_inst, query)){
322 radlog(L_ERR, "sqlippool_command: database query error in: '%s'", query);
326 (data->sql_inst->module->sql_finish_query)(sqlsocket,
327 data->sql_inst->config);
332 * Query the database expecting a single result row
334 static int sqlippool_query1(char * out, int outlen, const char * fmt,
335 SQLSOCK * sqlsocket, rlm_sqlippool_t *data,
336 REQUEST * request, char * param, int param_len)
338 char expansion[MAX_STRING_LEN * 4];
339 char query[MAX_STRING_LEN * 4];
340 int rlen, retval = 0;
342 sqlippool_expand(expansion, sizeof(expansion),
343 fmt, data, param, param_len);
346 * Do an xlat on the provided string
349 if (!radius_xlat(query, sizeof(query), expansion, request, data->sql_inst->sql_escape_func)) {
350 radlog(L_ERR, "sqlippool_command: xlat failed.");
356 strcpy(query, expansion);
359 if (data->sql_inst->sql_select_query(sqlsocket, data->sql_inst, query)){
360 radlog(L_ERR, "sqlippool_query1: database query error");
367 if (!data->sql_inst->sql_fetch_row(sqlsocket, data->sql_inst)) {
368 if (sqlsocket->row) {
369 if (sqlsocket->row[0]) {
370 if ((rlen = strlen(sqlsocket->row[0])) < outlen) {
371 strcpy(out, sqlsocket->row[0]);
374 RDEBUG("insufficient string space");
377 RDEBUG("row[0] returned NULL");
380 RDEBUG("SQL query did not return any results");
383 RDEBUG("SQL query did not succeed");
386 (data->sql_inst->module->sql_finish_select_query)(sqlsocket,
387 data->sql_inst->config);
391 static int sqlippool_detach(void *instance)
398 * Do any per-module initialization that is separate to each
399 * configured instance of the module. e.g. set up connections
400 * to external databases, read configuration files, set up
401 * dictionary entries, etc.
403 * If configuration information is given in the config section
404 * that must be referenced in later calls, store a handle to it
405 * in *instance otherwise put a null pointer there.
407 static int sqlippool_instantiate(CONF_SECTION * conf, void ** instance)
409 module_instance_t *modinst;
410 rlm_sqlippool_t * data;
411 const char * pool_name = NULL;
414 * Set up a storage area for instance data
416 data = rad_malloc(sizeof(*data));
417 memset(data, 0, sizeof(*data));
420 * If the configuration parameters can't be parsed, then
423 if (cf_section_parse(conf, data, module_config) < 0) {
428 if ((data->sql_instance_name == NULL) ||
429 (strlen(data->sql_instance_name) == 0)) {
430 radlog(L_ERR, "rlm_sqlippool: the 'sql-instance-name' variable must be set.");
431 sqlippool_detach(data);
436 * Check that all the queries are in place
439 if ((data->allocate_clear == NULL) ||
440 (strlen(data->allocate_clear) == 0)) {
441 radlog(L_ERR, "rlm_sqlippool: the 'allocate-clear' statement must be set.");
442 sqlippool_detach(data);
446 if ((data->allocate_find == NULL) ||
447 (strlen(data->allocate_find) == 0)) {
448 radlog(L_ERR, "rlm_sqlippool: the 'allocate_find' statement must be set.");
449 sqlippool_detach(data);
453 if ((data->allocate_update == NULL) ||
454 (strlen(data->allocate_update) == 0)) {
455 radlog(L_ERR, "rlm_sqlippool: the 'allocate_update' statement must be set.");
456 sqlippool_detach(data);
460 if ((data->start_update == NULL) ||
461 (strlen(data->start_update) == 0)) {
462 radlog(L_ERR, "rlm_sqlippool: the 'start-update' statement must be set.");
463 sqlippool_detach(data);
467 if ((data->alive_update == NULL) ||
468 (strlen(data->alive_update) == 0)) {
469 radlog(L_ERR, "rlm_sqlippool: the 'alive-update' statement must be set.");
470 sqlippool_detach(data);
474 if ((data->stop_clear == NULL) ||
475 (strlen(data->stop_clear) == 0)) {
476 radlog(L_ERR, "rlm_sqlippool: the 'stop-clear' statement must be set.");
477 sqlippool_detach(data);
481 if ((data->on_clear == NULL) ||
482 (strlen(data->on_clear) == 0)) {
483 radlog(L_ERR, "rlm_sqlippool: the 'on-clear' statement must be set.");
484 sqlippool_detach(data);
488 if ((data->off_clear == NULL) ||
489 (strlen(data->off_clear) == 0)) {
490 radlog(L_ERR, "rlm_sqlippool: the 'off-clear' statement must be set.");
491 sqlippool_detach(data);
495 pool_name = cf_section_name2(conf);
496 if (pool_name != NULL)
497 data->pool_name = strdup(pool_name);
499 data->pool_name = strdup("ippool");
501 modinst = find_module_instance(cf_section_find("modules"),
502 data->sql_instance_name, 1);
504 radlog(L_ERR, "sqlippool_instantiate: failed to find sql instance named %s", data->sql_instance_name);
505 sqlippool_detach(data);
509 if (strcmp(modinst->entry->name, "rlm_sql") != 0) {
510 radlog(L_ERR, "sqlippool_instantiate: Module \"%s\""
511 " is not an instance of the rlm_sql module",
512 data->sql_instance_name);
513 sqlippool_detach(data);
517 data->sql_inst = (SQL_INST *) modinst->insthandle;
525 * if we have something to log, then we log it
526 * otherwise we return the retcode as soon as possible
528 static int do_logging(char *str, int retcode)
530 if (str && (*str != '\0'))
531 radlog(L_INFO,"%s", str);
537 * Allocate an IP number from the pool.
539 static int sqlippool_postauth(void *instance, REQUEST * request)
541 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
542 char allocation[MAX_STRING_LEN];
544 uint32_t ip_allocation;
548 char logstr[MAX_STRING_LEN];
549 char sqlusername[MAX_STRING_LEN];
552 * If there is a Framed-IP-Address attribute in the reply do nothing
554 if (pairfind(request->reply->vps, PW_FRAMED_IP_ADDRESS, 0) != NULL) {
555 /* We already have a Framed-IP-Address */
556 radius_xlat(logstr, sizeof(logstr), data->log_exists,
558 RDEBUG("Framed-IP-Address already exists");
560 return do_logging(logstr, RLM_MODULE_NOOP);
563 if (pairfind(request->config_items, PW_POOL_NAME, 0) == NULL) {
564 RDEBUG("No Pool-Name defined.");
565 radius_xlat(logstr, sizeof(logstr), data->log_nopool,
568 return do_logging(logstr, RLM_MODULE_NOOP);
571 sqlsocket = data->sql_inst->sql_get_socket(data->sql_inst);
572 if (sqlsocket == NULL) {
573 RDEBUG("cannot allocate sql connection");
574 return RLM_MODULE_FAIL;
577 if (data->sql_inst->sql_set_user(data->sql_inst, request, sqlusername, NULL) < 0) {
578 return RLM_MODULE_FAIL;
584 sqlippool_command(data->allocate_begin, sqlsocket, data, request,
590 sqlippool_command(data->allocate_clear, sqlsocket, data, request,
596 allocation_len = sqlippool_query1(allocation, sizeof(allocation),
597 data->allocate_find, sqlsocket,
598 data, request, (char *) NULL, 0);
603 if (allocation_len == 0) {
607 sqlippool_command(data->allocate_commit, sqlsocket, instance,
608 request, (char *) NULL, 0);
611 * Should we perform pool-check ?
613 if (data->pool_check && *data->pool_check) {
616 * Ok, so the allocate-find query found nothing ...
617 * Let's check if the pool exists at all
619 allocation_len = sqlippool_query1(allocation, sizeof(allocation),
620 data->pool_check, sqlsocket, data, request,
623 data->sql_inst->sql_release_socket(data->sql_inst, sqlsocket);
625 if (allocation_len) {
628 * Pool exists after all... So,
629 * the failure to allocate the IP
630 * address was most likely due to
631 * the depletion of the pool. In
632 * that case, we should return
635 RDEBUG("pool appears to be full");
636 radius_xlat(logstr, sizeof(logstr), data->log_failed, request, NULL);
637 return do_logging(logstr, RLM_MODULE_NOTFOUND);
642 * Pool doesn't exist in the table. It
643 * may be handled by some other instance of
644 * sqlippool, so we should just ignore this
645 * allocation failure and return NOOP
647 RDEBUG("IP address could not be allocated as no pool exists with that name.");
648 return RLM_MODULE_NOOP;
652 data->sql_inst->sql_release_socket(data->sql_inst, sqlsocket);
654 RDEBUG("IP address could not be allocated.");
655 radius_xlat(logstr, sizeof(logstr), data->log_failed,
658 return do_logging(logstr, RLM_MODULE_NOOP);
663 * FIXME: Make it work with the ipv6 addresses
665 if ((ip_hton(allocation, AF_INET, &ipaddr) < 0) ||
666 ((ip_allocation = ipaddr.ipaddr.ip4addr.s_addr) == INADDR_NONE)) {
670 sqlippool_command(data->allocate_commit, sqlsocket, instance,
671 request, (char *) NULL, 0);
673 RDEBUG("Invalid IP number [%s] returned from database query.", allocation);
674 data->sql_inst->sql_release_socket(data->sql_inst, sqlsocket);
675 radius_xlat(logstr, sizeof(logstr), data->log_failed,
678 return do_logging(logstr, RLM_MODULE_NOOP);
684 sqlippool_command(data->allocate_update, sqlsocket, data, request,
685 allocation, allocation_len);
687 RDEBUG("Allocated IP %s [%08x]", allocation, ip_allocation);
689 vp = radius_paircreate(request, &request->reply->vps,
690 PW_FRAMED_IP_ADDRESS, 0, PW_TYPE_IPADDR);
691 vp->vp_ipaddr = ip_allocation;
696 sqlippool_command(data->allocate_commit, sqlsocket, data, request,
699 data->sql_inst->sql_release_socket(data->sql_inst, sqlsocket);
700 radius_xlat(logstr, sizeof(logstr), data->log_success, request, NULL);
702 return do_logging(logstr, RLM_MODULE_OK);
705 static int sqlippool_accounting_start(SQLSOCK * sqlsocket,
706 rlm_sqlippool_t *data, REQUEST *request)
711 sqlippool_command(data->start_begin, sqlsocket, data, request,
717 sqlippool_command(data->start_update, sqlsocket, data, request,
723 sqlippool_command(data->start_commit, sqlsocket, data, request,
726 return RLM_MODULE_OK;
729 static int sqlippool_accounting_alive(SQLSOCK * sqlsocket,
730 rlm_sqlippool_t *data, REQUEST *request)
735 sqlippool_command(data->alive_begin, sqlsocket, data, request,
741 sqlippool_command(data->alive_update, sqlsocket, data, request,
747 sqlippool_command(data->alive_commit, sqlsocket, data, request,
750 return RLM_MODULE_OK;
753 static int sqlippool_accounting_stop(SQLSOCK * sqlsocket,
754 rlm_sqlippool_t *data, REQUEST *request)
756 char logstr[MAX_STRING_LEN];
761 sqlippool_command(data->stop_begin, sqlsocket, data, request,
767 sqlippool_command(data->stop_clear, sqlsocket, data, request,
773 sqlippool_command(data->stop_commit, sqlsocket, data, request,
776 radius_xlat(logstr, sizeof(logstr), data->log_clear, request, NULL);
778 return do_logging(logstr, RLM_MODULE_OK);
781 static int sqlippool_accounting_on(SQLSOCK * sqlsocket,
782 rlm_sqlippool_t *data, REQUEST *request)
787 sqlippool_command(data->on_begin, sqlsocket, data, request,
793 sqlippool_command(data->on_clear, sqlsocket, data, request,
799 sqlippool_command(data->on_commit, sqlsocket, data, request,
802 return RLM_MODULE_OK;
805 static int sqlippool_accounting_off(SQLSOCK * sqlsocket,
806 rlm_sqlippool_t *data, REQUEST *request)
811 sqlippool_command(data->off_begin, sqlsocket, data, request,
817 sqlippool_command(data->off_clear, sqlsocket, data, request,
823 sqlippool_command(data->off_commit, sqlsocket, data, request,
826 return RLM_MODULE_OK;
830 * Check for an Accounting-Stop
831 * If we find one and we have allocated an IP to this nas/port
832 * combination, then deallocate it.
834 static int sqlippool_accounting(void * instance, REQUEST * request)
838 int acct_status_type;
839 rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
841 char sqlusername[MAX_STRING_LEN];
843 vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE, 0);
845 RDEBUG("Could not find account status type in packet.");
846 return RLM_MODULE_NOOP;
848 acct_status_type = vp->vp_integer;
850 switch (acct_status_type) {
851 case PW_STATUS_START:
852 case PW_STATUS_ALIVE:
854 case PW_STATUS_ACCOUNTING_ON:
855 case PW_STATUS_ACCOUNTING_OFF:
856 break; /* continue through to the next section */
859 /* We don't care about any other accounting packet */
860 return RLM_MODULE_NOOP;
863 sqlsocket = data->sql_inst->sql_get_socket(data->sql_inst);
864 if (sqlsocket == NULL) {
865 RDEBUG("cannot allocate sql connection");
866 return RLM_MODULE_NOOP;
869 if (data->sql_inst->sql_set_user(data->sql_inst, request, sqlusername, NULL) < 0) {
870 return RLM_MODULE_FAIL;
873 switch (acct_status_type) {
874 case PW_STATUS_START:
875 rcode = sqlippool_accounting_start(sqlsocket, data, request);
878 case PW_STATUS_ALIVE:
879 rcode = sqlippool_accounting_alive(sqlsocket, data, request);
883 rcode = sqlippool_accounting_stop(sqlsocket, data, request);
886 case PW_STATUS_ACCOUNTING_ON:
887 rcode = sqlippool_accounting_on(sqlsocket, data, request);
890 case PW_STATUS_ACCOUNTING_OFF:
891 rcode = sqlippool_accounting_off(sqlsocket, data, request);
895 /* We don't care about any other accounting packet */
896 return RLM_MODULE_NOOP;
899 data->sql_inst->sql_release_socket(data->sql_inst, sqlsocket);
905 * The module name should be the only globally exported symbol.
906 * That is, everything else should be 'static'.
908 * If the module needs to temporarily modify it's instantiation
909 * data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
910 * The server will then take care of ensuring that the module
911 * is single-threaded.
913 module_t rlm_sqlippool = {
916 RLM_TYPE_THREAD_SAFE, /* type */
917 sqlippool_instantiate, /* instantiation */
918 sqlippool_detach, /* detach */
920 NULL, /* authentication */
921 NULL, /* authorization */
922 NULL, /* preaccounting */
923 sqlippool_accounting, /* accounting */
924 NULL, /* checksimul */
925 NULL, /* pre-proxy */
926 NULL, /* post-proxy */
927 sqlippool_postauth /* post-auth */