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

📄 rlm_sqlippool.c

📁 新的radius程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  rlm_sqlippool.c     rlm_sqlippool - FreeRADIUS SQL IP Pool Module * * Version:     $Id: rlm_sqlippool.c,v 1.3.2.6 2007/07/17 18:46:32 pnixon 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 "autoconf.h"#include "libradius.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <netinet/in.h>#include "radiusd.h"#include "modules.h"#include "conffile.h"#include "modpriv.h"#include <rlm_sql.h>static const char rcsid[] = "$Id: rlm_sqlippool.c,v 1.3.2.6 2007/07/17 18:46:32 pnixon Exp $";/* *	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 */				/* 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 */	#ifdef HAVE_PTHREAD_H	pthread_mutex_t dlock;	long owner;#endif	} rlm_sqlippool_t;#ifndef HAVE_PTHREAD_H/* *  This is easier than ifdef's throughout the code. */#define pthread_mutex_init(_x, _y)#define pthread_mutex_destroy(_x)#define pthread_mutex_lock(_x)#define pthread_mutex_unlock(_x)#endif/* *	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, "BEGIN" },  { "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" },  { "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-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-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-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-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" },  { 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 */	int openbraces;	openbraces = 0;	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 != '\\') {			/*			 * We check if we're inside an open brace.  If we are			 * then we assume this brace is NOT literal, but is			 * a closing brace and apply it 			 */			if((c == '}') && openbraces) {				openbraces--;				continue;			}			*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 */				strNcpy(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);						q += strlen(q);					}					else {						memcpy(q, param, param_len);						q += param_len;					}				}				break;			case 'J': /* lease duration */				sprintf(tmp, "%d", data->lease_duration);				strNcpy(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.");			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");		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];	SQL_ROW row;	int r;	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;	}	r = rlm_sql_fetch_row(sqlsocket, data->sql_inst);	(data->sql_inst->module->sql_finish_select_query)(sqlsocket, data->sql_inst->config);	if (r) {		DEBUG("sqlippool_query1: SQL query did not succeed");		out[0] = '\0';		return 0;	}	row = sqlsocket->row;	if (row == NULL) {		DEBUG("sqlippool_query1: SQL query did not return any results");		out[0] = '\0';		return 0;	}	if (row[0] == NULL){		DEBUG("sqlippool_query1: row[0] returned NULL");		out[0] = '\0';		return 0;	}	r = strlen(row[0]);	if (r >= outlen){		DEBUG("sqlippool_query1: insufficient string space");		out[0] = '\0';		return 0;	}	strncpy(out, row[0], r);	out[r] = '\0';	return r;}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;}/* *	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){	rlm_sqlippool_t * data;	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.");		free(data);		exit(0);	}	/*	 *	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.");		free(data);		exit(0);	}	if (data->allocate_find == NULL || strlen(data->allocate_find) == 0) {		radlog(L_ERR, "rlm_sqlippool: the 'allocate_find' statement must be set.");		free(data);		exit(0);	}	if (data->allocate_update == NULL || strlen(data->allocate_update) == 0) {		radlog(L_ERR, "rlm_sqlippool: the 'allocate_update' statement must be set.");		free(data);		exit(0);	}	if (data->start_update == NULL || strlen(data->start_update) == 0) {		radlog(L_ERR, "rlm_sqlippool: the 'start-update' statement must be set.");		free(data);		exit(0);	}	if (data->alive_update == NULL || strlen(data->alive_update) == 0) {		radlog(L_ERR, "rlm_sqlippool: the 'alive-update' statement must be set.");		free(data);		exit(0);	}

⌨️ 快捷键说明

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