⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rlm_sqlippool.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  rlm_sqlippool.c     rlm_sqlippool - FreeRADIUS SQL IP Pool Module * * Version:  $Id: rlm_sqlippool.c,v 1.38 2008/04/28 12:25:23 aland Exp $ * *   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 distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * Copyright 2002  Globe.Net Communications Limited * Copyright 2006  The FreeRADIUS server project * Copyright 2006  Suntel Communications */#include <freeradius-devel/ident.h>RCSID("$Id: rlm_sqlippool.c,v 1.38 2008/04/28 12:25:23 aland Exp $")#include <freeradius-devel/radiusd.h>#include <ctype.h>#include <freeradius-devel/modules.h>#include <freeradius-devel/modpriv.h>#include <rlm_sql.h>/* *	Define a structure for our module configuration. */typedef struct rlm_sqlippool_t {	char *sql_instance_name;	int lease_duration;	SQL_INST *sql_inst;	char *pool_name;	/* We ended up removing the init	   queries so that its up to user	   to create the db structure and put the required	   information in there	*/				/* Allocation sequence */	char *allocate_begin;	/* SQL query to begin */	char *allocate_clear;	/* SQL query to clear an IP */	char *allocate_find;	/* SQL query to find an unused IP */	char *allocate_update;	/* SQL query to mark an IP as used */	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 *start_commit;	/* SQL query to commit */	char *start_rollback;	/* SQL query to rollback */				/* Alive sequence */	char *alive_begin;	/* SQL query to begin */	char *alive_update;	/* SQL query to update an IP entry */	char *alive_commit;	/* SQL query to commit */	char *alive_rollback;	/* SQL query to rollback */				/* Stop sequence */	char *stop_begin;	/* SQL query to begin */	char *stop_clear;	/* SQL query to clear an IP */	char *stop_commit;	/* SQL query to commit */	char *stop_rollback;	/* SQL query to rollback */				/* On sequence */	char *on_begin;		/* SQL query to begin */	char *on_clear;		/* SQL query to clear an entire NAS */	char *on_commit;	/* SQL query to commit */	char *on_rollback;	/* SQL query to rollback */				/* Off sequence */	char *off_begin;	/* SQL query to begin */	char *off_clear;	/* SQL query to clear an entire NAS */	char *off_commit;	/* SQL query to commit */	char *off_rollback;	/* SQL query to rollback */				/* Logging Section */	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 none in the check items */} rlm_sqlippool_t;/* *	A mapping of configuration file names to internal variables. * *	Note that the string is dynamically allocated, so it MUST *	be freed.  When the configuration file parse re-reads the string, *	it free's the old one, and strdup's the new one, placing the pointer *	to the strdup'd string into 'config.string'.  This gets around *	buffer over-flows. */static CONF_PARSER module_config[] = {  {"sql-instance-name",PW_TYPE_STRING_PTR,   offsetof(rlm_sqlippool_t,sql_instance_name), NULL, "sql"},  { "lease-duration", PW_TYPE_INTEGER,    offsetof(rlm_sqlippool_t,lease_duration), NULL, "86400"},  { "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, "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" },  { "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, "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, "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, "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, "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 }};/* *	Replace %<whatever> in a string. * *	%P	pool_name *	%I	param *	%J	lease_duration * */static int sqlippool_expand(char * out, int outlen, const char * fmt,			    void * instance, char * param, int param_len){	rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;	char *q;	const char *p;	char tmp[40]; /* For temporary storing of integers */	q = out;	for (p = fmt; *p ; p++) {		int freespace;		int c;		/* Calculate freespace in output */		freespace = outlen - (q - out);		if (freespace <= 1)			break;		c = *p;		if (c != '%' && c != '$' && c != '\\') {			*q++ = *p;			continue;		}		if (*++p == '\0')			break;		if (c == '\\') {			switch(*p) {			case '\\':				*q++ = '\\';				break;			case 't':				*q++ = '\t';				break;			case 'n':				*q++ = '\n';				break;			default:				*q++ = c;				*q++ = *p;				break;			}		}		else if (c == '%') {			switch(*p) {			case '%':				*q++ = *p;				break;			case 'P': /* pool name */				strlcpy(q, data->pool_name, freespace);				q += strlen(q);				break;			case 'I': /* IP address */				if (param && param_len > 0) {					if (param_len > freespace) {						strlcpy(q, param, freespace);						q += strlen(q);					}					else {						memcpy(q, param, param_len);						q += param_len;					}				}				break;			case 'J': /* lease duration */				sprintf(tmp, "%d", data->lease_duration);				strlcpy(q, tmp, freespace);				q += strlen(q);				break;			default:				*q++ = '%';				*q++ = *p;				break;			}		}	}	*q = '\0';#if 0	DEBUG2("sqlippool_expand: '%s'", out);#endif	return strlen(out);}/* * Query the database executing a command with no result rows */static int sqlippool_command(const char * fmt, SQLSOCK * sqlsocket,			     void * instance, REQUEST * request,			     char * param, int param_len){	rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;	char expansion[MAX_STRING_LEN * 4];	char query[MAX_STRING_LEN * 4];	sqlippool_expand(expansion, sizeof(expansion),			 fmt, instance, param, param_len);	/*	 * Do an xlat on the provided string	 */	if (request) {		char sqlusername[MAX_STRING_LEN];		if(sql_set_user(data->sql_inst, request, sqlusername, NULL) < 0) {			return RLM_MODULE_FAIL;		}		if (!radius_xlat(query, sizeof(query), expansion, request, NULL)) {			radlog(L_ERR, "sqlippool_command: xlat failed on: '%s'", query);			return 0;		}	} else {		strcpy(query, expansion);	}#if 0	DEBUG2("sqlippool_command: '%s'", query);#endif	if (rlm_sql_query(sqlsocket, data->sql_inst, query)){		radlog(L_ERR, "sqlippool_command: database query error in: '%s'", query);		return 0;	}	(data->sql_inst->module->sql_finish_query)(sqlsocket,						   data->sql_inst->config);	return 0;}/* * Query the database expecting a single result row */static int sqlippool_query1(char * out, int outlen, const char * fmt,			    SQLSOCK * sqlsocket, void * instance,			    REQUEST * request, char * param, int param_len){	rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;	char expansion[MAX_STRING_LEN * 4];	char query[MAX_STRING_LEN * 4];	int rlen, retval = 0;	sqlippool_expand(expansion, sizeof(expansion),			 fmt, instance, param, param_len);	/*	 * Do an xlat on the provided string	 */	if (request) {		char sqlusername[MAX_STRING_LEN];		if(sql_set_user(data->sql_inst, request, sqlusername, NULL) < 0) {			return RLM_MODULE_FAIL;		}		if (!radius_xlat(query, sizeof(query), expansion, request, NULL)) {			radlog(L_ERR, "sqlippool_command: xlat failed.");			out[0] = '\0';			return 0;		}	}	else {		strcpy(query, expansion);	}#if 0	DEBUG2("sqlippool_query1: '%s'", query);#endif	if (rlm_sql_select_query(sqlsocket, data->sql_inst, query)){		radlog(L_ERR, "sqlippool_query1: database query error");		out[0] = '\0';		return 0;	}	out[0] = '\0';	if (!rlm_sql_fetch_row(sqlsocket, data->sql_inst)) {		if (sqlsocket->row) {			if (sqlsocket->row[0]) {				if ((rlen = strlen(sqlsocket->row[0])) < outlen) {					strcpy(out, sqlsocket->row[0]);					retval = rlen;				} else {					DEBUG("sqlippool_query1: insufficient string space");				}			} else {				DEBUG("sqlippool_query1: row[0] returned NULL");			}		} else {			DEBUG("sqlippool_query1: SQL query did not return any results");		}	} else {		DEBUG("sqlippool_query1: SQL query did not succeed");	}	(data->sql_inst->module->sql_finish_select_query)(sqlsocket,							  data->sql_inst->config);	return retval;}static int sqlippool_initialize_sql(void * instance){	rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance;	SQLSOCK * sqlsocket;	sqlsocket = sql_get_socket(data->sql_inst);	if (sqlsocket == NULL) {		DEBUG("rlm_sqlippool: cannot allocate sql connection for initialization sequence");		return 0;	}	return 1;}static int sqlippool_detach(void *instance){	free(instance);	return 0;}/* *	Do any per-module initialization that is separate to each *	configured instance of the module.  e.g. set up connections *	to external databases, read configuration files, set up *	dictionary entries, etc. * *	If configuration information is given in the config section *	that must be referenced in later calls, store a handle to it *	in *instance otherwise put a null pointer there. */static int sqlippool_instantiate(CONF_SECTION * conf, void ** instance){	module_instance_t *modinst;	rlm_sqlippool_t * data;	const char * pool_name = NULL;	/*	 *	Set up a storage area for instance data	 */	data = rad_malloc(sizeof(*data));	memset(data, 0, sizeof(*data));	/*	 *	If the configuration parameters can't be parsed, then	 *	fail.	 */	if (cf_section_parse(conf, data, module_config) < 0) {		free(data);		return -1;	}	if ((data->sql_instance_name == NULL) ||	    (strlen(data->sql_instance_name) == 0)) {		radlog(L_ERR, "rlm_sqlippool: the 'sql-instance-name' variable must be set.");		sqlippool_detach(data);		return -1;	}	/*	 *	Check that all the queries are in place	 */	if ((data->allocate_clear == NULL) ||	    (strlen(data->allocate_clear) == 0)) {		radlog(L_ERR, "rlm_sqlippool: the 'allocate-clear' statement must be set.");		sqlippool_detach(data);		return -1;	}	if ((data->allocate_find == NULL) || 	    (strlen(data->allocate_find) == 0)) {		radlog(L_ERR, "rlm_sqlippool: the 'allocate_find' statement must be set.");		sqlippool_detach(data);		return -1;	}	if ((data->allocate_update == NULL) ||	    (strlen(data->allocate_update) == 0)) {		radlog(L_ERR, "rlm_sqlippool: the 'allocate_update' statement must be set.");		sqlippool_detach(data);		return -1;	}	if ((data->start_update == NULL) ||	    (strlen(data->start_update) == 0)) {		radlog(L_ERR, "rlm_sqlippool: the 'start-update' statement must be set.");		sqlippool_detach(data);		return -1;	}	if ((data->alive_update == NULL) ||

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -