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

📄 valuepair.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * valuepair.c	Valuepair functions that are radiusd-specific *		and as such do not belong in the library. * * Version:	$Id: valuepair.c,v 1.90 2008/03/07 09:49:49 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * Copyright 2000,2006  The FreeRADIUS server project * Copyright 2000  Alan DeKok <aland@ox.org> */#include <freeradius-devel/ident.h>RCSID("$Id: valuepair.c,v 1.90 2008/03/07 09:49:49 aland Exp $")#include <freeradius-devel/radiusd.h>#include <freeradius-devel/rad_assert.h>#ifdef HAVE_REGEX_H#	include <regex.h>/* *  For POSIX Regular expressions. *  (0) Means no extended regular expressions. *  REG_EXTENDED means use extended regular expressions. */#ifndef REG_EXTENDED#define REG_EXTENDED (0)#endif#ifndef REG_NOSUB#define REG_NOSUB (0)#endif#endifstruct cmp {	int attribute;	int otherattr;	void *instance; /* module instance */	RAD_COMPARE_FUNC compare;	struct cmp *next;};static struct cmp *cmp;int radius_compare_vps(REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *vp){	int ret = -2;	/*	 *      Check for =* and !* and return appropriately	 */	if( check->operator == T_OP_CMP_TRUE )	         return 0;	if( check->operator == T_OP_CMP_FALSE )	         return 1;#ifdef HAVE_REGEX_H	if (check->operator == T_OP_REG_EQ) {		int i, compare;		regex_t reg;		char name[1024];		char value[1024];		regmatch_t rxmatch[REQUEST_MAX_REGEX + 1];		snprintf(name, sizeof(name), "%%{%s}", check->name);		radius_xlat(value, sizeof(value), name, request, NULL);		/*		 *	Include substring matches.		 */		regcomp(&reg, (char *)check->vp_strvalue,			REG_EXTENDED);		compare = regexec(&reg, value,  REQUEST_MAX_REGEX + 1,				  rxmatch, 0);		regfree(&reg);		/*		 *	Add %{0}, %{1}, etc.		 */		for (i = 0; i <= REQUEST_MAX_REGEX; i++) {			char *p;			char buffer[sizeof(check->vp_strvalue)];			/*			 *	Didn't match: delete old			 *	match, if it existed.			 */			if ((compare != 0) ||			    (rxmatch[i].rm_so == -1)) {				p = request_data_get(request, request,						     REQUEST_DATA_REGEX | i);				if (p) {					free(p);					continue;				}				/*				 *	No previous match				 *	to delete, stop.				 */				break;			}			/*			 *	Copy substring into buffer.			 */			memcpy(buffer, value + rxmatch[i].rm_so,			       rxmatch[i].rm_eo - rxmatch[i].rm_so);			buffer[rxmatch[i].rm_eo - rxmatch[i].rm_so] = '\0';			/*			 *	Copy substring, and add it to			 *	the request.			 *			 *	Note that we don't check			 *	for out of memory, which is			 *	the only error we can get...			 */			p = strdup(buffer);			request_data_add(request, request,					 REQUEST_DATA_REGEX | i,					 p, free);		}		if (compare == 0) return 0;		return -1;	}	if (check->operator == T_OP_REG_NE) {		int compare;		regex_t reg;		char name[1024];		char value[1024];		regmatch_t rxmatch[REQUEST_MAX_REGEX + 1];		snprintf(name, sizeof(name), "%%{%s}", check->name);		radius_xlat(value, sizeof(value), name, request, NULL);		/*		 *	Include substring matches.		 */		regcomp(&reg, (char *)check->vp_strvalue,			REG_EXTENDED);		compare = regexec(&reg, value,  REQUEST_MAX_REGEX + 1,				  rxmatch, 0);		regfree(&reg);		if (compare != 0) return 0;		return -1;	}#endif	/*	 *	Tagged attributes are equal if and only if both the	 *	tag AND value match.	 */	if ((ret == 0) && check->flags.has_tag) {		ret = ((int) vp->flags.tag) - ((int) check->flags.tag);		if (ret != 0) return ret;	}	/*	 *	Not a regular expression, compare the types.	 */	switch(check->type) {#ifdef ASCEND_BINARY		/*		 *	Ascend binary attributes can be treated		 *	as opaque objects, I guess...		 */		case PW_TYPE_ABINARY:#endif		case PW_TYPE_OCTETS:			if (vp->length != check->length) {				ret = 1; /* NOT equal */				break;			}			ret = memcmp(vp->vp_strvalue, check->vp_strvalue,				     vp->length);			break;		case PW_TYPE_STRING:			ret = strcmp((char *)vp->vp_strvalue,				     (char *)check->vp_strvalue);			break;		case PW_TYPE_BYTE:		case PW_TYPE_SHORT:		case PW_TYPE_INTEGER:			ret = vp->vp_integer - check->vp_integer;			break;		case PW_TYPE_DATE:			ret = vp->vp_date - check->vp_date;			break;		case PW_TYPE_IPADDR:			ret = ntohl(vp->vp_ipaddr) - ntohl(check->vp_ipaddr);			break;		case PW_TYPE_IPV6ADDR:			ret = memcmp(&vp->vp_ipv6addr, &check->vp_ipv6addr,				     sizeof(vp->vp_ipv6addr));			break;		case PW_TYPE_IPV6PREFIX:			ret = memcmp(&vp->vp_ipv6prefix, &check->vp_ipv6prefix,				     sizeof(vp->vp_ipv6prefix));			break;		case PW_TYPE_IFID:			ret = memcmp(&vp->vp_ifid, &check->vp_ifid,				     sizeof(vp->vp_ifid));			break;		default:			break;	}	return ret;}/* *	Compare 2 attributes. May call the attribute compare function. */int radius_callback_compare(REQUEST *req, VALUE_PAIR *request,			    VALUE_PAIR *check, VALUE_PAIR *check_pairs,			    VALUE_PAIR **reply_pairs){	struct cmp *c;	/*	 *      Check for =* and !* and return appropriately	 */	if( check->operator == T_OP_CMP_TRUE )	         return 0;  /* always return 0/EQUAL */	if( check->operator == T_OP_CMP_FALSE )	         return 1;  /* always return 1/NOT EQUAL */	/*	 *	See if there is a special compare function.	 *	 *	FIXME: use new RB-Tree code.	 */	for (c = cmp; c; c = c->next)		if (c->attribute == check->attribute) {			return (c->compare)(c->instance, req, request, check,				check_pairs, reply_pairs);		}	if (!request) return -1; /* doesn't exist, don't compare it */	return radius_compare_vps(req, check, request);}/* *	See what attribute we want to compare with. */static int otherattr(int attr){	struct cmp	*c;	for (c = cmp; c; c = c->next) {		if (c->attribute == attr)			return c->otherattr;	}	return attr;}/* *	Register a function as compare function. *	compare_attr is the attribute in the request we want to *	compare with. Normally this is the same as "attr". *	You can set this to: * *	-1   the same as "attr" *	0    always call compare function, not tied to request attribute *	>0   Attribute to compare with. * *	For example, PW_GROUP in a check item needs to be compared *	with PW_USER_NAME in the incoming request. */int paircompare_register(int attr, int compare_attr, RAD_COMPARE_FUNC fun, void *instance){	struct cmp	*c;	paircompare_unregister(attr, fun);	c = rad_malloc(sizeof(struct cmp));	c->compare = fun;	c->attribute = attr;	c->otherattr = compare_attr;	c->instance = instance;	c->next = cmp;	cmp = c;	return 0;}/* *	Unregister a function. */void paircompare_unregister(int attr, RAD_COMPARE_FUNC fun){	struct cmp	*c, *last;	last = NULL;	for (c = cmp; c; c = c->next) {		if (c->attribute == attr && c->compare == fun)			break;		last = c;	}	if (c == NULL) return;	if (last != NULL)		last->next = c->next;	else		cmp = c->next;	free(c);}/* *	Compare two pair lists except for the password information. *	For every element in "check" at least one matching copy must *	be present in "reply". * *	Return 0 on match. */int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR **reply){	VALUE_PAIR *check_item;	VALUE_PAIR *auth_item;	int result = 0;	int compare;	int other;	for (check_item = check; check_item != NULL; check_item = check_item->next) {		/*		 *	If the user is setting a configuration value,		 *	then don't bother comparing it to any attributes		 *	sent to us by the user.  It ALWAYS matches.		 */		if ((check_item->operator == T_OP_SET) ||		    (check_item->operator == T_OP_ADD)) {			continue;		}		switch (check_item->attribute) {			/*

⌨️ 快捷键说明

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