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

📄 valuepair.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * valuepair.c	Functions to handle VALUE_PAIRs * * Version:	$Id: valuepair.c,v 1.141 2008/04/18 14:09:56 aland Exp $ * *   This library is free software; you can redistribute it and/or *   modify it under the terms of the GNU Lesser General Public *   License as published by the Free Software Foundation; either *   version 2.1 of the License, or (at your option) any later version. * *   This library 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 *   Lesser General Public License for more details. * *   You should have received a copy of the GNU Lesser General Public *   License along with this library; 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 */#include <freeradius-devel/ident.h>RCSID("$Id: valuepair.c,v 1.141 2008/04/18 14:09:56 aland Exp $")#include	<freeradius-devel/libradius.h>#include	<ctype.h>#ifdef HAVE_MALLOC_H#  include	<malloc.h>#endif#ifdef HAVE_REGEX_H#  include	<regex.h>#endifstatic const char *months[] = {        "jan", "feb", "mar", "apr", "may", "jun",        "jul", "aug", "sep", "oct", "nov", "dec" };/* *	This padding is necessary only for attributes that are NOT *	in the dictionary, and then only because the rest of the *	code accesses vp->name directly, rather than through an *	accessor function. * *	The name padding only has to large enough for: * *		Vendor-65535-Attr-65535 * *	i.e. 23 characters, plus a zero.  We add another 8 bytes for *	padding, because the VALUE_PAIR structure may be un-aligned. * *	The result is that for the normal case, the server uses a less *	memory (36 bytes * number of VALUE_PAIRs). */#define FR_VP_NAME_PAD (32)#define FR_VP_NAME_LEN (24)VALUE_PAIR *pairalloc(DICT_ATTR *da){	size_t name_len = 0;	VALUE_PAIR *vp;	/*	 *	Not in the dictionary: the name is allocated AFTER	 *	the VALUE_PAIR struct.	 */	if (!da) name_len = FR_VP_NAME_PAD;	vp = malloc(sizeof(*vp) + name_len);	if (!vp) return NULL;	memset(vp, 0, sizeof(*vp));	if (da) {		vp->attribute = da->attr;		vp->vendor = da->vendor;		vp->type = da->type;		vp->name = da->name;		vp->flags = da->flags;	} else {		vp->attribute = 0;		vp->vendor = 0;		vp->type = PW_TYPE_OCTETS;		vp->name = NULL;		memset(&vp->flags, 0, sizeof(vp->flags));		vp->flags.unknown_attr = 1;	}	switch (vp->type) {		case PW_TYPE_BYTE:			vp->length = 1;			break;		case PW_TYPE_SHORT:			vp->length = 2;			break;		case PW_TYPE_INTEGER:		case PW_TYPE_IPADDR:		case PW_TYPE_DATE:			vp->length = 4;			break;		case PW_TYPE_IFID:			vp->length = sizeof(vp->vp_ifid);			break;		case PW_TYPE_IPV6ADDR:			vp->length = sizeof(vp->vp_ipv6addr);			break;		case PW_TYPE_IPV6PREFIX:			vp->length = sizeof(vp->vp_ipv6prefix);			break;		case PW_TYPE_ETHERNET:			vp->length = sizeof(vp->vp_ether);			break;		default:			vp->length = 0;			break;	}	return vp;}/* *	Create a new valuepair. */VALUE_PAIR *paircreate(int attr, int type){	VALUE_PAIR	*vp;	DICT_ATTR	*da;	da = dict_attrbyvalue(attr);	if ((vp = pairalloc(da)) == NULL) {		librad_log("out of memory");		return NULL;	}	vp->operator = T_OP_EQ;	/*	 *	It isn't in the dictionary: update the name.	 */	if (!da) {		char *p = (char *) (vp + 1);				vp->vendor = VENDOR(attr);		vp->attribute = attr;		vp->name = p;		vp->type = type; /* be forgiving */		if (!vp_print_name(p, FR_VP_NAME_LEN, vp->attribute)) {			free(vp);			return NULL;		}	}	return vp;}/* *      release the memory used by a single attribute-value pair *      just a wrapper around free() for now. */void pairbasicfree(VALUE_PAIR *pair){	/* clear the memory here */	memset(pair, 0, sizeof(*pair));	free(pair);}/* *	Release the memory used by a list of attribute-value *	pairs, and sets the pair pointer to NULL. */void pairfree(VALUE_PAIR **pair_ptr){	VALUE_PAIR	*next, *pair;	if (!pair_ptr) return;	pair = *pair_ptr;	while (pair != NULL) {		next = pair->next;		pairbasicfree(pair);		pair = next;	}	*pair_ptr = NULL;}/* *	Find the pair with the matching attribute */VALUE_PAIR * pairfind(VALUE_PAIR *first, int attr){	while(first && first->attribute != attr)		first = first->next;	return first;}/* *	Delete the pair(s) with the matching attribute */void pairdelete(VALUE_PAIR **first, int attr){	VALUE_PAIR *i, *next;	VALUE_PAIR **last = first;	for(i = *first; i; i = next) {		next = i->next;		if (i->attribute == attr) {			*last = next;			pairbasicfree(i);		} else {			last = &i->next;		}	}}/* *	Add a pair at the end of a VALUE_PAIR list. */void pairadd(VALUE_PAIR **first, VALUE_PAIR *add){	VALUE_PAIR *i;	if (!add) return;	if (*first == NULL) {		*first = add;		return;	}	for(i = *first; i->next; i = i->next)		;	i->next = add;}/* *	Add or replace a pair at the end of a VALUE_PAIR list. */void pairreplace(VALUE_PAIR **first, VALUE_PAIR *replace){	VALUE_PAIR *i, *next;	VALUE_PAIR **prev = first;	if (*first == NULL) {		*first = replace;		return;	}	/*	 *	Not an empty list, so find item if it is there, and	 *	replace it. Note, we always replace the first one, and	 *	we ignore any others that might exist.	 */	for(i = *first; i; i = next) {		next = i->next;		/*		 *	Found the first attribute, replace it,		 *	and return.		 */		if (i->attribute == replace->attribute) {			*prev = replace;			/*			 *	Should really assert that replace->next == NULL			 */			replace->next = next;			pairbasicfree(i);			return;		}		/*		 *	Point to where the attribute should go.		 */		prev = &i->next;	}	/*	 *	If we got here, we didn't find anything to replace, so	 *	stopped at the last item, which we just append to.	 */	*prev = replace;}/* *	Copy just one VP. */VALUE_PAIR *paircopyvp(const VALUE_PAIR *vp){	size_t name_len;	VALUE_PAIR *n;		if (!vp->flags.unknown_attr) {		name_len = 0;	} else {		name_len = FR_VP_NAME_PAD;	}		if ((n = malloc(sizeof(*n) + name_len)) == NULL) {		librad_log("out of memory");		return NULL;	}	memcpy(n, vp, sizeof(*n) + name_len);	n->next = NULL;	return n;}/* *	Copy just a certain type of pairs. */VALUE_PAIR *paircopy2(VALUE_PAIR *vp, int attr){	VALUE_PAIR	*first, *n, **last;	first = NULL;	last = &first;	while (vp) {		if (attr >= 0 && vp->attribute != attr) {			vp = vp->next;			continue;		}		n = paircopyvp(vp);		if (!n) return first;		*last = n;		last = &n->next;		vp = vp->next;	}	return first;}/* *	Copy a pairlist. */VALUE_PAIR *paircopy(VALUE_PAIR *vp){	return paircopy2(vp, -1);}/* *	Move attributes from one list to the other *	if not already present. */void pairmove(VALUE_PAIR **to, VALUE_PAIR **from){	VALUE_PAIR **tailto, *i, *j, *next;	VALUE_PAIR *tailfrom = NULL;	VALUE_PAIR *found;	int has_password = 0;	/*	 *	First, see if there are any passwords here, and	 *	point "tailto" to the end of the "to" list.	 */	tailto = to;	for(i = *to; i; i = i->next) {		if (i->attribute == PW_USER_PASSWORD ||		    i->attribute == PW_CRYPT_PASSWORD)			has_password = 1;		tailto = &i->next;	}	/*	 *	Loop over the "from" list.	 */	for(i = *from; i; i = next) {		next = i->next;		/*		 *	If there was a password in the "to" list,		 *	do not move any other password from the		 *	"from" to the "to" list.		 */		if (has_password &&		    (i->attribute == PW_USER_PASSWORD ||		     i->attribute == PW_CRYPT_PASSWORD)) {			tailfrom = i;			continue;		}		switch (i->operator) {			/*			 *	These are COMPARISON attributes			 *	from a check list, and are not			 *	supposed to be copied!			 */			case T_OP_NE:			case T_OP_GE:			case T_OP_GT:			case T_OP_LE:			case T_OP_LT:			case T_OP_CMP_TRUE:			case T_OP_CMP_FALSE:			case T_OP_CMP_EQ:				tailfrom = i;				continue;			default:				break;		}		/*		 *	If the attribute is already present in "to",		 *	do not move it from "from" to "to". We make		 *	an exception for "Hint" which can appear multiple		 *	times, and we never move "Fall-Through".		 */		if (i->attribute == PW_FALL_THROUGH ||		    (i->attribute != PW_HINT && i->attribute != PW_FRAMED_ROUTE)) {			found = pairfind(*to, i->attribute);			switch (i->operator) {			  /*			   *	If matching attributes are found,			   *	delete them.			   */			case T_OP_SUB:		/* -= */				if (found) {					if (!i->vp_strvalue[0] ||					    (strcmp((char *)found->vp_strvalue,						    (char *)i->vp_strvalue) == 0)){						pairdelete(to, found->attribute);						/*						 *	'tailto' may have been						 *	deleted...						 */						tailto = to;						for(j = *to; j; j = j->next) {							tailto = &j->next;						}					}				}				tailfrom = i;				continue;				break;/* really HAVE_REGEX_H */#if 0				/*				 *  Attr-Name =~ "s/find/replace/"				 *				 *  Very bad code.  Barely working,				 *  if at all.				 */			case T_OP_REG_EQ:			  if (found &&			      (i->vp_strvalue[0] == 's')) {			    regex_t		reg;			    regmatch_t		match[1];			    char *str;			    char *p, *q;			    p = i->vp_strvalue + 1;			    q = strchr(p + 1, *p);			    if (!q || (q[strlen(q) - 1] != *p)) {			      tailfrom = i;			      continue;			    }			    str = strdup(i->vp_strvalue + 2);			    q = strchr(str, *p);			    *(q++) = '\0';			    q[strlen(q) - 1] = '\0';			    regcomp(&reg, str, 0);			    if (regexec(&reg, found->vp_strvalue,					1, match, 0) == 0) {			      fprintf(stderr, "\"%s\" will have %d to %d replaced with %s\n",				      found->vp_strvalue, match[0].rm_so,				      match[0].rm_eo, q);			    }			    regfree(&reg);			    free(str);			  }			  tailfrom = i;	/* don't copy it over */			  continue;			  break;#endif			case T_OP_EQ:		/* = */				/*				 *  FIXME: Tunnel attributes with				 *  different tags are different				 *  attributes.				 */				if (found) {					tailfrom = i;					continue; /* with the loop */				}				break;			  /*			   *  If a similar attribute is found,			   *  replace it with the new one.  Otherwise,			   *  add the new one to the list.			   */			case T_OP_SET:		/* := */				if (found) {					VALUE_PAIR *mynext = found->next;					/*					 *	Do NOT call pairdelete()					 *	here, due to issues with					 *	re-writing "request->username".					 *					 *	Everybody calls pairmove,					 *	and expects it to work.					 *	We can't update request->username					 *	here, so instead we over-write					 *	the vp that it's pointing to.					 */					memcpy(found, i, sizeof(*found));					found->next = mynext;					pairdelete(&found->next, found->attribute);					/*					 *	'tailto' may have been					 *	deleted...					 */					for(j = found; j; j = j->next) {						tailto = &j->next;					}					continue;				}				break;			  /*			   *  Add the new element to the list, even			   *  if similar ones already exist.			   */			default:			case T_OP_ADD: /* += */				break;			}		}		if (tailfrom)			tailfrom->next = next;		else			*from = next;		/*		 *	If ALL of the 'to' attributes have been deleted,		 *	then ensure that the 'tail' is updated to point		 *	to the head.		 */		if (!*to) {			tailto = to;		}		*tailto = i;		if (i) {			i->next = NULL;			tailto = &i->next;		}	}}/* *	Move one kind of attributes from one list to the other */void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, int attr){	VALUE_PAIR *to_tail, *i, *next;	VALUE_PAIR *iprev = NULL;	/*	 *	Find the last pair in the "to" list and put it in "to_tail".	 */	if (*to != NULL) {		to_tail = *to;		for(i = *to; i; i = i->next)			to_tail = i;	} else		to_tail = NULL;	for(i = *from; i; i = next) {		next = i->next;		/*		 *	If the attribute to move is NOT a VSA, then it		 *	ignores any attributes which do not match exactly.		 */		if ((attr != PW_VENDOR_SPECIFIC) &&		    (i->attribute != attr)) {			iprev = i;			continue;		}		/*		 *	If the attribute to move IS a VSA, then it ignores		 *	any non-VSA attribute.		 */		if ((attr == PW_VENDOR_SPECIFIC) &&		    (VENDOR(i->attribute) == 0)) {			iprev = i;			continue;		}		/*		 *	Remove the attribute from the "from" list.		 */		if (iprev)			iprev->next = next;		else			*from = next;		/*		 *	Add the attribute to the "to" list.		 */		if (to_tail)			to_tail->next = i;		else			*to = i;		to_tail = i;		i->next = NULL;	}}/* *	Sort of strtok/strsep function. */static char *mystrtok(char **ptr, const char *sep){	char	*res;	if (**ptr == 0)		return NULL;	while (**ptr && strchr(sep, **ptr))		(*ptr)++;	if (**ptr == 0)		return NULL;	res = *ptr;	while (**ptr && strchr(sep, **ptr) == NULL)

⌨️ 快捷键说明

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