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

📄 rlm_sqlcounter.c

📁 free radius编程。完成AAA的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * rlm_sqlcounter.c * * Version:  $Id: rlm_sqlcounter.c,v 1.11 2004/05/15 15:50:26 mgriego 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 2001  The FreeRADIUS server project * Copyright 2001  Alan DeKok <aland@ox.org> *//* This module is based directly on the rlm_counter module */#include "config.h"#include "autoconf.h"#include "libradius.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "radiusd.h"#include "modules.h"#include "conffile.h"#define MAX_QUERY_LEN 1024#include <time.h>/* 	Note: When your counter spans more than 1 period (ie 3 months or 2 weeks), this module *	probably does NOT do what you want!  It calculates the range of dates to count across *	by first calculating the End of the Current period and then subtracting the number of *	periods you specify from that to determine the beginning of the range. * *	For example, if you specify a 3 month counter and today is June 15th, the end of the current *	period is June 30. Subtracting 3 months from that gives April 1st.  So, the counter will *	sum radacct entries from April 1st to June 30. Then, next month, it will sum entries *	from May 1st to July 31st. * *	To fix this behavior, we need to add some way of storing the Next Reset Time */static const char rcsid[] = "$Id: rlm_sqlcounter.c,v 1.11 2004/05/15 15:50:26 mgriego Exp $";/* *	Define a structure for our module configuration. * *	These variables do not need to be in a structure, but it's *	a lot cleaner to do so, and a pointer to the structure can *	be used as the instance handle. */typedef struct rlm_sqlcounter_t {	char *counter_name;  	/* Daily-Session-Time */	char *check_name;  	/* Max-Daily-Session */	char *key_name;  	/* User-Name */	char *sqlmod_inst;	/* instance of SQL module to use, usually just 'sql' */	char *query;		/* SQL query to retrieve current session time */	char *reset;  		/* daily, weekly, monthly, never or user defined */	time_t reset_time;	time_t last_reset;	int  key_attr;		/* attribute number for key field */	int  dict_attr;		/* attribute number for the counter. */} rlm_sqlcounter_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[] = {  { "counter-name", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,counter_name), NULL,  NULL },  { "check-name", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,check_name), NULL, NULL },  { "key", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,key_name), NULL, NULL },  { "sqlmod-inst", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,sqlmod_inst), NULL, NULL },  { "query", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,query), NULL, NULL },  { "reset", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,reset), NULL,  NULL },  { NULL, -1, 0, NULL, NULL }};static int find_next_reset(rlm_sqlcounter_t *data, time_t timeval){	int ret=0;	unsigned int num=1;	char last = 0;	struct tm *tm, s_tm;	char sCurrentTime[40], sNextTime[40];	tm = localtime_r(&timeval, &s_tm);	strftime(sCurrentTime, sizeof(sCurrentTime),"%Y-%m-%d %H:%M:%S",tm);	tm->tm_sec = tm->tm_min = 0;	if (data->reset == NULL)		return -1;	if (isdigit((int) data->reset[0])){		unsigned int len=0;		len = strlen(data->reset);		if (len == 0)			return -1;		last = data->reset[len - 1];		if (!isalpha((int) last))			last = 'd';/*		num = atoi(data->reset); */		DEBUG("rlm_sqlcounter: num=%d, last=%c",num,last);	}	if (strcmp(data->reset, "hourly") == 0 || last == 'h') {		/*		 *  Round up to the next nearest hour.		 */		tm->tm_hour += num;		data->reset_time = mktime(tm);	} else if (strcmp(data->reset, "daily") == 0 || last == 'd') {		/*		 *  Round up to the next nearest day.		 */		tm->tm_hour = 0;		tm->tm_mday += num;		data->reset_time = mktime(tm);	} else if (strcmp(data->reset, "weekly") == 0 || last == 'w') {		/*		 *  Round up to the next nearest week.		 */		tm->tm_hour = 0;		tm->tm_mday += (7 - tm->tm_wday) +(7*(num-1));		data->reset_time = mktime(tm);	} else if (strcmp(data->reset, "monthly") == 0 || last == 'm') {		tm->tm_hour = 0;		tm->tm_mday = 1;		tm->tm_mon += num;		data->reset_time = mktime(tm);	} else if (strcmp(data->reset, "never") == 0) {		data->reset_time = 0;	} else {		radlog(L_ERR, "rlm_sqlcounter: Unknown reset timer \"%s\"",			data->reset);		return -1;	}	strftime(sNextTime, sizeof(sNextTime),"%Y-%m-%d %H:%M:%S",tm);	DEBUG2("rlm_sqlcounter: Current Time: %d [%s], Next reset %d [%s]",		(int)timeval,sCurrentTime,(int)data->reset_time, sNextTime);	return ret;}/*  I don't believe that this routine handles Daylight Saving Time adjustments    properly.  Any suggestions?*/static int find_prev_reset(rlm_sqlcounter_t *data, time_t timeval){	int ret=0;	unsigned int num=1;	char last = 0;	struct tm *tm, s_tm;	char sCurrentTime[40], sPrevTime[40];	tm = localtime_r(&timeval, &s_tm);	strftime(sCurrentTime, sizeof(sCurrentTime),"%Y-%m-%d %H:%M:%S",tm);	tm->tm_sec = tm->tm_min = 0;	if (data->reset == NULL)		return -1;	if (isdigit((int) data->reset[0])){		unsigned int len=0;		len = strlen(data->reset);		if (len == 0)			return -1;		last = data->reset[len - 1];		if (!isalpha((int) last))			last = 'd';		num = atoi(data->reset);		DEBUG("rlm_sqlcounter: num=%d, last=%c",num,last);	}	if (strcmp(data->reset, "hourly") == 0 || last == 'h') {		/*		 *  Round down to the prev nearest hour.		 */		tm->tm_hour -= num - 1;		data->last_reset = mktime(tm);	} else if (strcmp(data->reset, "daily") == 0 || last == 'd') {		/*		 *  Round down to the prev nearest day.		 */		tm->tm_hour = 0;		tm->tm_mday -= num - 1;		data->last_reset = mktime(tm);	} else if (strcmp(data->reset, "weekly") == 0 || last == 'w') {		/*		 *  Round down to the prev nearest week.		 */		tm->tm_hour = 0;		tm->tm_mday -= (7 - tm->tm_wday) +(7*(num-1));		data->last_reset = mktime(tm);	} else if (strcmp(data->reset, "monthly") == 0 || last == 'm') {		tm->tm_hour = 0;		tm->tm_mday = 1;		tm->tm_mon -= num - 1;		data->last_reset = mktime(tm);	} else if (strcmp(data->reset, "never") == 0) {		data->reset_time = 0;	} else {		radlog(L_ERR, "rlm_sqlcounter: Unknown reset timer \"%s\"",			data->reset);		return -1;	}	strftime(sPrevTime, sizeof(sPrevTime),"%Y-%m-%d %H:%M:%S",tm);	DEBUG2("rlm_sqlcounter: Current Time: %d [%s], Prev reset %d [%s]",		(int)timeval,sCurrentTime,(int)data->last_reset, sPrevTime);	return ret;}/* *	Replace %<whatever> in a string. * *	%b	last_reset *	%e	reset_time *	%k	key_name *	%S	sqlmod_inst * */static int sqlcounter_expand(char *out, int outlen, const char *fmt, void *instance){	rlm_sqlcounter_t *data = (rlm_sqlcounter_t *) instance;	int c,freespace;	const char *p;	char *q;	char tmpdt[40]; /* For temporary storing of dates */	int openbraces=0;	q = out;	for (p = fmt; *p ; p++) {	/* 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++ = *p;				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;			case 'b': /* last_reset */				sprintf(tmpdt, "%lu", data->last_reset);				strNcpy(q, tmpdt, freespace);				q += strlen(q);				break;			case 'e': /* reset_time */				sprintf(tmpdt, "%lu", data->reset_time);				strNcpy(q, tmpdt, freespace);				q += strlen(q);				break;			case 'k': /* Key Name */				strNcpy(q, data->key_name, freespace);				q += strlen(q);				break;			case 'S': /* SQL module instance */				strNcpy(q, data->sqlmod_inst, freespace);				q += strlen(q);				break;			default:				*q++ = '%';				*q++ = *p;				break;		}	}	*q = '\0';	DEBUG2("sqlcounter_expand:  '%s'", out);	return strlen(out);}/* *	See if the counter matches. */static int sqlcounter_cmp(void *instance, REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check,		VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs){	rlm_sqlcounter_t *data = (rlm_sqlcounter_t *) instance;	int counter;	char querystr[MAX_QUERY_LEN];	char responsestr[MAX_QUERY_LEN];

⌨️ 快捷键说明

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