#include <freeradius-devel/ident.h>
RCSID("$Id$")
-#include <freeradius-devel/autoconf.h>
-#include <freeradius-devel/libradius.h>
+#include <freeradius-devel/radiusd.h>
-#include <stdlib.h>
#include <ctype.h>
-#include <freeradius-devel/radiusd.h>
#include <freeradius-devel/modules.h>
#include <freeradius-devel/modpriv.h>
char *allocate_commit; /* SQL query to commit */
char *allocate_rollback; /* SQL query to rollback */
+ char *pool_check; /* Query to check for the existence of the pool */
+
/* Start sequence */
char *start_begin; /* SQL query to begin */
char *start_update; /* SQL query to update an IP entry */
char *off_rollback; /* SQL query to rollback */
/* Logging Section */
-
- char *log_exists; /* There Was an ip address already asigned */
+ char *log_exists; /* There was an ip address already assigned */
char *log_success; /* We successfully allocated ip address from pool */
+ char *log_clear; /* We successfully deallocated ip address from pool */
char *log_failed; /* Failed to allocate ip from the pool */
char *log_nopool; /* There was no Framed-IP-Address but also no Pool-Name */
/* Reserved to handle 255.255.255.254 Requests */
- char *defaultpool; /* Default Pool-Name if there is non in the check items */
+ char *defaultpool; /* Default Pool-Name if there is non in the check items */
} rlm_sqlippool_t;
{ "pool-name" , PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, pool_name), NULL, ""},
- { "allocate-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_begin), NULL, "BEGIN" },
+ { "allocate-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_begin), NULL, "START TRANSACTION" },
{ "allocate-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_clear), NULL, "" },
{ "allocate-find", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_find), NULL, "" },
{ "allocate-update", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_update), NULL, "" },
{ "allocate-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_commit), NULL, "COMMIT" },
{ "allocate-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,allocate_rollback), NULL, "ROLLBACK" },
- { "start-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_begin), NULL, "BEGIN" },
+ { "pool-check", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,pool_check), NULL, "" },
+
+ { "start-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_begin), NULL, "START TRANSACTION" },
{ "start-update", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_update), NULL, "" },
{ "start-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_commit), NULL, "COMMIT" },
{ "start-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,start_rollback), NULL, "ROLLBACK" },
- { "alive-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_begin), NULL, "BEGIN" },
+ { "alive-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_begin), NULL, "START TRANSACTION" },
{ "alive-update", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_update), NULL, "" },
{ "alive-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_commit), NULL, "COMMIT" },
{ "alive-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,alive_rollback), NULL, "ROLLBACK" },
- { "stop-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_begin), NULL, "BEGIN" },
+ { "stop-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_begin), NULL, "START TRANSACTION" },
{ "stop-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_clear), NULL, "" },
{ "stop-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_commit), NULL, "COMMIT" },
{ "stop-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,stop_rollback), NULL, "ROLLBACK" },
- { "on-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_begin), NULL, "BEGIN" },
+ { "on-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_begin), NULL, "START TRANSACTION" },
{ "on-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_clear), NULL, "" },
{ "on-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_commit), NULL, "COMMIT" },
{ "on-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,on_rollback), NULL, "ROLLBACK" },
- { "off-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_begin), NULL, "BEGIN" },
+ { "off-begin", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_begin), NULL, "START TRANSACTION" },
{ "off-clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_clear), NULL, "" },
{ "off-commit", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_commit), NULL, "COMMIT" },
{ "off-rollback", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t,off_rollback), NULL, "ROLLBACK" },
{ "sqlippool_log_exists", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_exists), NULL, "" },
{ "sqlippool_log_success", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_success), NULL, "" },
+ { "sqlippool_log_clear", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_clear), NULL, "" },
{ "sqlippool_log_failed", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_failed), NULL, "" },
{ "sqlippool_log_nopool", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, log_nopool), NULL, "" },
{ "defaultpool", PW_TYPE_STRING_PTR, offsetof(rlm_sqlippool_t, defaultpool), NULL, "main_pool" },
-
-
{ NULL, -1, 0, NULL, NULL }
};
*q++ = *p;
break;
case 'P': /* pool name */
- strNcpy(q, data->pool_name, freespace);
+ strlcpy(q, data->pool_name, freespace);
q += strlen(q);
break;
case 'I': /* IP address */
if (param && param_len > 0) {
if (param_len > freespace) {
- strNcpy(q, param, freespace);
+ strlcpy(q, param, freespace);
q += strlen(q);
}
else {
break;
case 'J': /* lease duration */
sprintf(tmp, "%d", data->lease_duration);
- strNcpy(q, tmp, freespace);
+ strlcpy(q, tmp, freespace);
q += strlen(q);
break;
default:
*/
if (request) {
if (!radius_xlat(query, sizeof(query), expansion, request, NULL)) {
- radlog(L_ERR, "sqlippool_command: xlat failed.");
+ radlog(L_ERR, "sqlippool_command: xlat failed on: '%s'", query);
return 0;
}
}
DEBUG2("sqlippool_command: '%s'", query);
#endif
if (rlm_sql_query(sqlsocket, data->sql_inst, query)){
- radlog(L_ERR, "sqlippool_command: database query error");
+ radlog(L_ERR, "sqlippool_command: database query error in: '%s'", query);
return 0;
}
}
-/* Do "hit and run!"
+/*
* if we have something to log, then we log it
* otherwise we return the retcode as soon as possible
- * </tuyan>
*/
static int do_logging(char *str, int retcode)
{
sqlsocket = sql_get_socket(data->sql_inst);
if (sqlsocket == NULL) {
DEBUG("rlm_sqlippool: cannot allocate sql connection");
- return RLM_MODULE_NOOP;
+ return RLM_MODULE_FAIL;
}
/*
sqlippool_command(data->allocate_commit, sqlsocket, instance, request,
(char *) NULL, 0);
- DEBUG("rlm_sqlippool: IP number could not be allocated.");
+ /*
+ * Should we perform pool-check ?
+ */
+ if (data->pool_check && *data->pool_check) {
+
+ /*
+ * Ok, so the allocate-find query found nothing ...
+ * Let's check if the pool exists at all
+ */
+ allocation_len = sqlippool_query1(allocation, sizeof(allocation),
+ data->pool_check, sqlsocket, instance, request,
+ (char *) NULL, 0);
+
+ sql_release_socket(data->sql_inst, sqlsocket);
+
+ if (allocation_len) {
+
+ /*
+ * Pool exists after all... So, the failure to allocate
+ * the IP address was most likely due to the depletion
+ * of the pool. In that case, we should return NOTFOUND
+ */
+ DEBUG("rlm_sqlippool: IP address could not be allocated.");
+ radius_xlat(logstr, sizeof(logstr), data->log_failed, request, NULL);
+ return do_logging(logstr, RLM_MODULE_NOTFOUND);
+
+ }
+ /*
+ * Pool doesn't exist in the table. It may be handled by some
+ * other instance of sqlippool, so we should just ignore
+ * this allocation failure and return NOOP
+ */
+ DEBUG("rlm_sqlippool: IP address could not be allocated as not pool exists with that name.");
+ return RLM_MODULE_NOOP;
+
+ }
+
sql_release_socket(data->sql_inst, sqlsocket);
+
+ DEBUG("rlm_sqlippool: IP address could not be allocated.");
radius_xlat(logstr, sizeof(logstr), data->log_failed, request, NULL);
-
- return do_logging(logstr, RLM_MODULE_NOTFOUND);
+
+ return do_logging(logstr, RLM_MODULE_NOOP);
}
static int sqlippool_accounting_stop(void * instance, REQUEST * request)
{
+ char logstr[MAX_STRING_LEN];
+
rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
SQLSOCK * sqlsocket;
(char *) NULL, 0);
sql_release_socket(data->sql_inst, sqlsocket);
+ radius_xlat(logstr, sizeof(logstr), data->log_clear, request, NULL);
- return RLM_MODULE_OK;
+ return do_logging(logstr, RLM_MODULE_OK);
}
static int sqlippool_accounting_on(void * instance, REQUEST * request)
{
rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;
- free(data->sql_instance_name);
- free(data->pool_name);
-
-
-
- free(data->allocate_begin);
- free(data->allocate_clear);
- free(data->allocate_find);
- free(data->allocate_update);
- free(data->allocate_commit);
- free(data->allocate_rollback);
-
- free(data->start_begin);
- free(data->start_update);
- free(data->start_commit);
- free(data->start_rollback);
-
- free(data->alive_begin);
- free(data->alive_update);
- free(data->alive_commit);
- free(data->alive_rollback);
-
- free(data->stop_begin);
- free(data->stop_clear);
- free(data->stop_commit);
- free(data->stop_rollback);
-
- free(data->on_begin);
- free(data->on_clear);
- free(data->on_commit);
- free(data->on_rollback);
-
- free(data->off_begin);
- free(data->off_clear);
- free(data->off_commit);
- free(data->off_rollback);
-
- free(data->log_exists);
- free(data->log_failed);
- free(data->log_nopool);
- free(data->log_success);
- free(data->defaultpool);
-
-
-
return 0;
}