| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894 | 
							- /*
 
-  * $Id: avpair.c,v 1.26 2010/06/15 09:22:52 aland Exp $
 
-  *
 
-  * Copyright (C) 1995 Lars Fenneberg
 
-  *
 
-  * Copyright 1992 Livingston Enterprises, Inc.
 
-  *
 
-  * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
 
-  * and Merit Network, Inc. All Rights Reserved
 
-  *
 
-  * See the file COPYRIGHT for the respective terms and conditions.
 
-  * If the file is missing contact me at lf@elemental.net
 
-  * and I'll send you a copy.
 
-  *
 
-  */
 
- #include <radius_config.h>
 
- #include <includes.h>
 
- #include <freeradius-client.h>
 
- #include "util.h"
 
- #include "def.h"
 
- /** Adds an attribute-value pair to the given list
 
-  *
 
-  * @note Always appends the new pair to the end of the list.
 
-  *
 
-  * @param rh a handle to parsed configuration.
 
-  * @param list a #VALUE_PAIR array of values; initially must be %NULL.
 
-  * @param attrid The attribute of the pair to add (e.g., %PW_USER_NAME).
 
-  * @param pval the value (e.g., the actual username).
 
-  * @param len the length of @pval, or -1 if to calculate (in case of strings).
 
-  * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
 
-  * @return pointer to added a/v pair upon success, NULL pointer upon failure.
 
-  */
 
- VALUE_PAIR *rc_avpair_add (rc_handle const *rh, VALUE_PAIR **list, int attrid, void const *pval, int len, int vendorpec)
 
- {
 
- 	VALUE_PAIR     *vp;
 
- 	vp = rc_avpair_new (rh, attrid, pval, len, vendorpec);
 
- 	if (vp != NULL)
 
- 	{
 
- 		rc_avpair_insert (list, NULL, vp);
 
- 	}
 
- 	return vp;
 
- }
 
- /** Assigns the given value to an attribute-value pair
 
-  *
 
-  * @param vp a pointer to a #VALUE_PAIR structure.
 
-  * @param pval the value (e.g., the actual username).
 
-  * @param len the length of @pval, or -1 if to calculate (in case of strings).
 
-  * @return 0 on success or -1 on failure.
 
-  */
 
- int rc_avpair_assign (VALUE_PAIR *vp, void const *pval, int len)
 
- {
 
- #if 1
 
- 	switch (vp->type)
 
- 	{
 
- 		case PW_TYPE_STRING:
 
- 			if (len == -1)
 
- 				len = (uint32_t)strlen((char const *)pval);
 
- 			if (len > AUTH_STRING_LEN) {
 
- 		        	rc_log(LOG_ERR, "rc_avpair_assign: bad attribute length");
 
- 		        	return -1;
 
- 			}
 
- 			memcpy(vp->strvalue, (char const *)pval, len);
 
- 			vp->strvalue[len] = '\0';
 
- 			vp->lvalue = len;
 
- 			break;
 
- 		case PW_TYPE_DATE:
 
- 		case PW_TYPE_INTEGER:
 
- 	        case PW_TYPE_IPADDR:
 
- 			vp->lvalue = * (uint32_t *) pval;
 
- 			break;
 
- 	        case PW_TYPE_IPV6ADDR:
 
- 			if (len != 16) {
 
- 		        	rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 length");
 
- 		        	return -1;
 
- 			}
 
- 			memcpy(vp->strvalue, (char const *)pval, len);
 
- 			vp->lvalue = len;
 
- 			break;
 
- 	        case PW_TYPE_IPV6PREFIX:
 
- 			if (len < 2 || len > 18) {
 
- 		        	rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 prefix length");
 
- 		        	return -1;
 
- 			}
 
- 			memcpy(vp->strvalue, (char const *)pval, len);
 
- 			vp->lvalue = len;
 
- 			break;
 
- 		default:
 
- 			rc_log(LOG_ERR, "rc_avpair_assign: unknown attribute %d", vp->type);
 
- 			return -1;
 
- 	}
 
- #endif    
 
- 	return 0;
 
- }
 
- /** Make a new attribute-value pair with given parameters
 
-  *
 
-  * @param rh a handle to parsed configuration.
 
-  * @param attrid The attribute of the pair to add (e.g., %PW_USER_NAME).
 
-  * @param pval the value (e.g., the actual username).
 
-  * @param len the length of pval, or -1 if to calculate (in case of strings).
 
-  * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
 
-  * @return pointer to generated a/v pair when successful, NULL when failure.
 
-  */
 
- VALUE_PAIR *rc_avpair_new (rc_handle const *rh, int attrid, void const *pval, int len, int vendorpec)
 
- {
 
-  
 
- 	VALUE_PAIR     *vp = NULL;
 
- 	DICT_ATTR      *pda;
 
- 	attrid = attrid | (vendorpec << 16);
 
- 	if ((pda = rc_dict_getattr (rh, attrid)) == NULL)
 
- 	{
 
- 		rc_log(LOG_ERR,"rc_avpair_new: unknown attribute %d", attrid);
 
- 		return NULL;
 
- 	}
 
- 	if (vendorpec != 0 && rc_dict_getvend(rh, vendorpec) == NULL)
 
- 	{
 
- 		rc_log(LOG_ERR,"rc_avpair_new: unknown Vendor-Id %d", vendorpec);
 
- 		return NULL;
 
- 	}
 
- 	if ((vp = malloc (sizeof (VALUE_PAIR))) != NULL)
 
- 	{
 
- 		strlcpy (vp->name, pda->name, sizeof (vp->name));
 
- 		vp->attribute = attrid;
 
- 		vp->next = NULL;
 
- 		vp->type = pda->type;
 
- 		if (rc_avpair_assign (vp, pval, len) == 0)
 
- 		{
 
- 			/* XXX: Fix up Digest-Attributes */
 
- 			switch (vp->attribute) {
 
- 			case PW_DIGEST_REALM:
 
- 			case PW_DIGEST_NONCE:
 
- 			case PW_DIGEST_METHOD:
 
- 			case PW_DIGEST_URI:
 
- 			case PW_DIGEST_QOP:
 
- 			case PW_DIGEST_ALGORITHM:
 
- 			case PW_DIGEST_BODY_DIGEST:
 
- 			case PW_DIGEST_CNONCE:
 
- 			case PW_DIGEST_NONCE_COUNT:
 
- 			case PW_DIGEST_USER_NAME:
 
- 				/* overlapping! */
 
- 				if (vp->lvalue > AUTH_STRING_LEN - 2)
 
- 					vp->lvalue = AUTH_STRING_LEN - 2;
 
- 				memmove(&vp->strvalue[2], &vp->strvalue[0], vp->lvalue);
 
- 				vp->strvalue[0] = vp->attribute - PW_DIGEST_REALM + 1;
 
- 				vp->lvalue += 2;
 
- 				vp->strvalue[1] = vp->lvalue;
 
- 				vp->strvalue[vp->lvalue] = '\0';
 
- 				vp->attribute = PW_DIGEST_ATTRIBUTES;
 
- 			default:
 
- 				break;
 
- 			}
 
- 			return vp;
 
- 		}
 
- 		free (vp);
 
- 		vp = NULL;
 
- 	}
 
- 	else
 
- 	{
 
- 		rc_log(LOG_CRIT,"rc_avpair_new: out of memory");
 
- 	}
 
- 	return vp;
 
- }
 
- /** Takes attribute/value pairs from buffer and builds a value_pair list using allocated memory
 
-  *
 
-  * @note Uses recursion.
 
-  *
 
-  * @param rh a handle to parsed configuration.
 
-  * @param pair a pointer to a #VALUE_PAIR structure.
 
-  * @param ptr the value (e.g., the actual username).
 
-  * @param length the length of ptr, or -1 if to calculate (in case of strings).
 
-  * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
 
-  * @return value_pair list or %NULL on failure.
 
-  */
 
- VALUE_PAIR *rc_avpair_gen(rc_handle const *rh, VALUE_PAIR *pair, unsigned char const *ptr,
 
- 			  int length, int vendorpec)
 
- {
 
- #if 1
 
- 	int attribute, attrlen, x_len;
 
- 	unsigned char const *x_ptr;
 
- 	uint32_t lvalue;
 
- 	DICT_ATTR *attr;
 
- 	VALUE_PAIR *rpair;
 
- 	char buffer[(AUTH_STRING_LEN * 2) + 1];
 
- 	/* For hex string conversion. */
 
- 	char hex[3];
 
- 	if (length < 2) {
 
- 		rc_log(LOG_ERR, "rc_avpair_gen: received attribute with "
 
- 		    "invalid length");
 
- 		goto shithappens;
 
- 	}
 
- 	attrlen = ptr[1];
 
- 	if (length < attrlen || attrlen < 2) {
 
- 		rc_log(LOG_ERR, "rc_avpair_gen: received attribute with "
 
- 		    "invalid length");
 
- 		goto shithappens;
 
- 	}
 
- 	/* Advance to the next attribute and process recursively */
 
- 	if (length != attrlen) {
 
- 		pair = rc_avpair_gen(rh, pair, ptr + attrlen, length - attrlen,
 
- 		    vendorpec);
 
- 		if (pair == NULL)
 
- 			return NULL;
 
- 	}
 
- 	/* Actual processing */
 
- 	attribute = ptr[0] | (vendorpec << 16);
 
- 	ptr += 2;
 
- 	attrlen -= 2;
 
- 	/* VSA */
 
- 	if (attribute == PW_VENDOR_SPECIFIC) {
 
- 		if (attrlen < 4) {
 
- 			rc_log(LOG_ERR, "rc_avpair_gen: received VSA "
 
- 			    "attribute with invalid length");
 
- 			goto skipit;
 
- 		}
 
- 		memcpy(&lvalue, ptr, 4);
 
- 		vendorpec = ntohl(lvalue);
 
- 		if (rc_dict_getvend(rh, vendorpec) == NULL) {
 
- 			/* Warn and skip over the unknown VSA */
 
- 			rc_log(LOG_WARNING, "rc_avpair_gen: received VSA "
 
- 			    "attribute with unknown Vendor-Id %d", vendorpec);
 
- 			goto skipit;
 
- 		}
 
- 		/* Process recursively */
 
- 		return rc_avpair_gen(rh, pair, ptr + 4, attrlen - 4,
 
- 		    vendorpec);
 
- 	}
 
- 	/* Normal */
 
- 	attr = rc_dict_getattr(rh, attribute);
 
- 	if (attr == NULL) {
 
- 		buffer[0] = '\0';	/* Initial length. */
 
- 		x_ptr = ptr;
 
- 		for (x_len = attrlen; x_len > 0; x_len--, x_ptr++) {
 
- 			snprintf(hex, sizeof(hex), "%2.2X", x_ptr[0]);
 
- 			strcat(buffer, hex);
 
- 		}
 
- 		if (vendorpec == 0) {
 
- 			rc_log(LOG_WARNING, "rc_avpair_gen: received "
 
- 			    "unknown attribute %d of length %d: 0x%s",
 
- 			    attribute, attrlen + 2, buffer);
 
- 		} else {
 
- 			rc_log(LOG_WARNING, "rc_avpair_gen: received "
 
- 			    "unknown VSA attribute %d, vendor %d of "
 
- 			    "length %d: 0x%s", attribute & 0xffff,
 
- 			    VENDOR(attribute), attrlen + 2, buffer);
 
- 		}
 
- 		goto skipit;
 
- 	}
 
- 	rpair = malloc(sizeof(*rpair));
 
- 	if (rpair == NULL) {
 
- 		rc_log(LOG_CRIT, "rc_avpair_gen: out of memory");
 
- 		goto shithappens;
 
- 	}
 
- 	memset(rpair, '\0', sizeof(*rpair));
 
- 	/* Insert this new pair at the beginning of the list */
 
- 	rpair->next = pair;
 
- 	pair = rpair;
 
- 	strcpy(pair->name, attr->name);
 
- 	pair->attribute = attr->value;
 
- 	pair->type = attr->type;
 
- 	switch (attr->type) {
 
- 	case PW_TYPE_STRING:
 
- 		memcpy(pair->strvalue, (char *)ptr, (size_t)attrlen);
 
- 		pair->strvalue[attrlen] = '\0';
 
- 		pair->lvalue = attrlen;
 
- 		break;
 
- 	case PW_TYPE_INTEGER:
 
- 		if (attrlen != 4) {
 
- 			rc_log(LOG_ERR, "rc_avpair_gen: received INT "
 
- 			    "attribute with invalid length");
 
- 			goto skipit;
 
- 		}
 
- 	case PW_TYPE_IPADDR:
 
- 		if (attrlen != 4) {
 
- 			rc_log(LOG_ERR, "rc_avpair_gen: received IPADDR"
 
- 			    " attribute with invalid length");
 
- 			goto skipit;
 
- 		}
 
- 		memcpy((char *)&lvalue, (char *)ptr, 4);
 
- 		pair->lvalue = ntohl(lvalue);
 
- 		break;
 
- 	case PW_TYPE_IPV6ADDR:
 
- 		if (attrlen != 16) {
 
- 			rc_log(LOG_ERR, "rc_avpair_gen: received IPV6ADDR"
 
- 			    " attribute with invalid length");
 
- 			goto skipit;
 
- 		}
 
- 		memcpy(pair->strvalue, (char *)ptr, 16);
 
- 		pair->lvalue = attrlen;
 
- 		break;
 
- 	case PW_TYPE_IPV6PREFIX:
 
- 		if (attrlen > 18 || attrlen < 2) {
 
- 			rc_log(LOG_ERR, "rc_avpair_gen: received IPV6PREFIX"
 
- 			    " attribute with invalid length: %d", attrlen);
 
- 			goto skipit;
 
- 		}
 
- 		memcpy(pair->strvalue, (char *)ptr, attrlen);
 
- 		pair->lvalue = attrlen;
 
- 		break;
 
- 	case PW_TYPE_DATE:
 
- 		if (attrlen != 4) {
 
- 			rc_log(LOG_ERR, "rc_avpair_gen: received DATE "
 
- 			    "attribute with invalid length");
 
- 			goto skipit;
 
- 		}
 
- 	default:
 
- 		rc_log(LOG_WARNING, "rc_avpair_gen: %s has unknown type",
 
- 		    attr->name);
 
- 		goto skipit;
 
- 	}
 
- skipit:
 
- 	return pair;
 
- shithappens:
 
- 	while (pair != NULL) {
 
- 		rpair = pair->next;
 
- 		free(pair);
 
- 		pair = rpair;
 
- 	}
 
- #endif    
 
- 	return NULL;
 
- }
 
- /** Find the first attribute value-pair (which matches the given attribute) from the specified value-pair list
 
-  *
 
-  * @param vp a pointer to a #VALUE_PAIR structure.
 
-  * @param attrid The attribute of the pair to find (e.g., %PW_USER_NAME).
 
-  * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
 
-  * @return the value pair found.
 
-  */
 
- VALUE_PAIR *rc_avpair_get (VALUE_PAIR *vp, int attrid, int vendorpec)
 
- {
 
- 	for (; vp != NULL && !(ATTRID(vp->attribute) == ATTRID(attrid) &&
 
- 	    VENDOR(vp->attribute) == vendorpec); vp = vp->next)
 
- 	{
 
- 		continue;
 
- 	}
 
-   
 
- 	return vp;
 
- }
 
- /** Insert a VALUE_PAIR into a list
 
-  *
 
-  * Given the address of an existing list "a" and a pointer to an entry "p" in that list, add the value pair "b" to
 
-  * the "a" list after the "p" entry.  If "p" is NULL, add the value pair "b" to the end of "a".
 
-  *
 
-  * @param a a #VALUE_PAIR array of values.
 
-  * @param p a pointer to a #VALUE_PAIR in a.
 
-  * @param b The #VALUE_PAIR pointer to add in a.
 
-  */
 
- void rc_avpair_insert(VALUE_PAIR **a, VALUE_PAIR *p, VALUE_PAIR *b)
 
- {
 
- 	VALUE_PAIR     *this_node = NULL;
 
- 	VALUE_PAIR     *vp;
 
- 	if (b->next != NULL)
 
- 	{
 
- 		rc_log(LOG_CRIT, "rc_avpair_insert: value pair (0x%p) next ptr. (0x%p) not NULL", b, b->next);
 
- 		abort ();
 
- 	}
 
- 	if (*a == NULL)
 
- 	{
 
- 		*a = b;
 
- 		return;
 
- 	}
 
- 	vp = *a;
 
- 	if ( p == NULL) /* run to end of "a" list */
 
- 	{
 
- 		while (vp != NULL)
 
- 		{
 
- 			this_node = vp;
 
- 			vp = vp->next;
 
- 		}
 
- 	}
 
- 	else /* look for the "p" entry in the "a" list */
 
- 	{
 
- 		this_node = *a;
 
- 		while (this_node != NULL)
 
- 		{
 
- 			if (this_node == p)
 
- 			{
 
- 				break;
 
- 			}
 
- 			this_node = this_node->next;
 
- 		}
 
- 	}
 
- 	b->next = this_node->next;
 
- 	this_node->next = b;
 
- 	return;
 
- }
 
- /** Frees all value_pairs in the list
 
-  *
 
-  * @param pair a pointer to a VALUE_PAIR structure.
 
-  */
 
- void rc_avpair_free (VALUE_PAIR *pair)
 
- {
 
- #if 0  
 
- 	VALUE_PAIR     *next;
 
- 	while (pair != NULL)
 
- 	{
 
- 		next = pair->next;
 
- 		free (pair);
 
- 		pair = next;
 
- 	}
 
- #endif    
 
- }
 
- /** Copy a data field from the buffer
 
-  *
 
-  * Advance the buffer past the data field. Ensure that no more than len - 1 bytes are copied and that resulting
 
-  * string is terminated with '\0'.
 
-  *
 
-  * @param string the provided string to copy.
 
-  * @param uptr the current position of the buffer.
 
-  * @param stopat characters to which parsing should stop.
 
-  * @param len the maximum length of string.
 
-  */
 
- static void rc_fieldcpy(char *string, char const **uptr, char const *stopat, size_t len)
 
- {
 
- #if 0  
 
- 	char const *ptr, *estring;
 
- 	ptr = *uptr;
 
- 	estring = string + len - 1;
 
- 	if (*ptr == '"')
 
- 	{
 
- 		ptr++;
 
- 		while (*ptr != '"' && *ptr != '\0' && *ptr != '\n')
 
- 		{
 
- 			if (string < estring)
 
- 				*string++ = *ptr;
 
- 			ptr++;
 
- 		}
 
- 		if (*ptr == '"')
 
- 		{
 
- 			ptr++;
 
- 		}
 
- 		*string = '\0';
 
- 		*uptr = ptr;
 
- 		return;
 
- 	}
 
- 	while (*ptr != '\0' && strchr(stopat, *ptr) == NULL)
 
- 	{
 
- 		if (string < estring)
 
- 			*string++ = *ptr;
 
- 		ptr++;
 
- 	}
 
- 	*string = '\0';
 
- 	*uptr = ptr;
 
- #endif
 
- 	return;
 
- }
 
- #define PARSE_MODE_NAME		0
 
- #define PARSE_MODE_EQUAL	1
 
- #define PARSE_MODE_VALUE	2
 
- #define PARSE_MODE_INVALID	3
 
- /** Parses the buffer to extract the attribute-value pairs
 
-  *
 
-  * @param rh a handle to parsed configuration.
 
-  * @param buffer the buffer to be parsed.
 
-  * @param first_pair an allocated array of values.
 
-  * @return 0 on successful parse of attribute-value pair, or -1 on syntax (or other) error detected.
 
-  */
 
- int rc_avpair_parse (rc_handle const *rh, char const *buffer, VALUE_PAIR **first_pair)
 
- {
 
- #if 0  
 
- 	int             mode;
 
- 	char            attrstr[AUTH_ID_LEN];
 
- 	char            valstr[AUTH_STRING_LEN + 1], *p;
 
- 	DICT_ATTR      *attr = NULL;
 
- 	DICT_VALUE     *dval;
 
- 	VALUE_PAIR     *pair;
 
- 	VALUE_PAIR     *link;
 
- 	struct tm      *tm;
 
- 	time_t          timeval;
 
- 	mode = PARSE_MODE_NAME;
 
- 	while (*buffer != '\n' && *buffer != '\0')
 
- 	{
 
- 		if (*buffer == ' ' || *buffer == '\t')
 
- 		{
 
- 			buffer++;
 
- 			continue;
 
- 		}
 
- 		switch (mode)
 
- 		{
 
- 		    case PARSE_MODE_NAME:		/* Attribute Name */
 
- 			rc_fieldcpy (attrstr, &buffer, " \t\n=,", sizeof(attrstr));
 
- 			if ((attr =
 
- 				rc_dict_findattr (rh, attrstr)) == NULL)
 
- 			{
 
- 				rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute");
 
- 				if (*first_pair) {
 
- 					rc_avpair_free(*first_pair);
 
- 					*first_pair = NULL;
 
- 				}
 
- 				return -1;
 
- 			}
 
- 			mode = PARSE_MODE_EQUAL;
 
- 			break;
 
- 		    case PARSE_MODE_EQUAL:		/* Equal sign */
 
- 			if (*buffer == '=')
 
- 			{
 
- 				mode = PARSE_MODE_VALUE;
 
- 				buffer++;
 
- 			}
 
- 			else
 
- 			{
 
- 				rc_log(LOG_ERR, "rc_avpair_parse: missing or misplaced equal sign");
 
- 				if (*first_pair) {
 
- 					rc_avpair_free(*first_pair);
 
- 					*first_pair = NULL;
 
- 				}
 
- 				return -1;
 
- 			}
 
- 			break;
 
- 		    case PARSE_MODE_VALUE:		/* Value */
 
- 			rc_fieldcpy (valstr, &buffer, " \t\n,", sizeof(valstr));
 
- 			if ((pair = malloc (sizeof (VALUE_PAIR))) == NULL)
 
- 			{
 
- 				rc_log(LOG_CRIT, "rc_avpair_parse: out of memory");
 
- 				if (*first_pair) {
 
- 					rc_avpair_free(*first_pair);
 
- 					*first_pair = NULL;
 
- 				}
 
- 				return -1;
 
- 			}
 
- 			strcpy (pair->name, attr->name);
 
- 			pair->attribute = attr->value;
 
- 			pair->type = attr->type;
 
- 			switch (pair->type)
 
- 			{
 
- 			    case PW_TYPE_STRING:
 
- 				strcpy (pair->strvalue, valstr);
 
- 				pair->lvalue = (uint32_t)strlen(valstr);
 
- 				break;
 
- 			    case PW_TYPE_INTEGER:
 
- 				if (isdigit (*valstr))
 
- 				{
 
- 					pair->lvalue = atoi (valstr);
 
- 				}
 
- 				else
 
- 				{
 
- 					if ((dval = rc_dict_findval (rh, valstr))
 
- 							== NULL)
 
- 					{
 
- 						rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute value: %s", valstr);
 
- 						if (*first_pair) {
 
- 							rc_avpair_free(*first_pair);
 
- 							*first_pair = NULL;
 
- 						}
 
- 						free (pair);
 
- 						return -1;
 
- 					}
 
- 					else
 
- 					{
 
- 						pair->lvalue = dval->value;
 
- 					}
 
- 				}
 
- 				break;
 
- 			    case PW_TYPE_IPADDR:
 
- 			    	if (inet_pton(AF_INET, valstr, &pair->lvalue) == 0) {
 
- 			    		rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv4 address %s", valstr);
 
- 			    		free(pair);
 
- 			    		return -1;
 
- 			    	}
 
-                                 pair->lvalue = ntohl(pair->lvalue);
 
- 				break;
 
- 			    case PW_TYPE_IPV6ADDR:
 
- 			    	if (inet_pton(AF_INET6, valstr, pair->strvalue) == 0) {
 
- 			    		rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 address %s", valstr);
 
- 			    		free(pair);
 
- 			    		return -1;
 
- 			    	}
 
- 				pair->lvalue = 16;
 
- 				break;
 
- 			    case PW_TYPE_IPV6PREFIX:
 
- 			    	p = strchr(valstr, '/');
 
- 			    	if (p == NULL) {
 
- 			    		rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr);
 
- 			    		free(pair);
 
- 			    		return -1;
 
- 			    	}
 
- 			    	*p = 0;
 
- 			    	p++;
 
- 			    	pair->strvalue[0] = 0;
 
- 			    	pair->strvalue[1] = atoi(p);
 
- 			    	if (inet_pton(AF_INET6, valstr, pair->strvalue+2) == 0) {
 
- 			    		rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr);
 
- 			    		free(pair);
 
- 			    		return -1;
 
- 			    	}
 
- 				pair->lvalue = 2+16;
 
- 				break;
 
- 			    case PW_TYPE_DATE:
 
- 				timeval = time (0);
 
- 				tm = localtime (&timeval);
 
- 				tm->tm_hour = 0;
 
- 				tm->tm_min = 0;
 
- 				tm->tm_sec = 0;
 
- 				rc_str2tm (valstr, tm);
 
- #ifdef TIMELOCAL
 
- 				pair->lvalue = (uint32_t) timelocal (tm);
 
- #else	/* TIMELOCAL */
 
- 				pair->lvalue = (uint32_t) mktime (tm);
 
- #endif	/* TIMELOCAL */
 
- 				break;
 
- 			    default:
 
- 				rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute type %d", pair->type);
 
- 				if (*first_pair) {
 
- 					rc_avpair_free(*first_pair);
 
- 					*first_pair = NULL;
 
- 				}
 
- 				free (pair);
 
- 				return -1;
 
- 			}
 
- 			/* XXX: Fix up Digest-Attributes */
 
- 			switch (pair->attribute) {
 
- 			case PW_DIGEST_REALM:
 
- 			case PW_DIGEST_NONCE:
 
- 			case PW_DIGEST_METHOD:
 
- 			case PW_DIGEST_URI:
 
- 			case PW_DIGEST_QOP:
 
- 			case PW_DIGEST_ALGORITHM:
 
- 			case PW_DIGEST_BODY_DIGEST:
 
- 			case PW_DIGEST_CNONCE:
 
- 			case PW_DIGEST_NONCE_COUNT:
 
- 			case PW_DIGEST_USER_NAME:
 
- 				/* overlapping! */
 
- 				if (pair->lvalue > AUTH_STRING_LEN - 2)
 
- 					pair->lvalue = AUTH_STRING_LEN - 2;
 
- 				memmove(&pair->strvalue[2], &pair->strvalue[0], pair->lvalue);
 
- 				pair->strvalue[0] = pair->attribute - PW_DIGEST_REALM + 1;
 
- 				pair->lvalue += 2;
 
- 				pair->strvalue[1] = pair->lvalue;
 
- 				pair->strvalue[pair->lvalue] = '\0';
 
- 				pair->attribute = PW_DIGEST_ATTRIBUTES;
 
- 			}
 
- 			pair->next = NULL;
 
- 			if (*first_pair == NULL)
 
- 			{
 
- 				*first_pair = pair;
 
- 			}
 
- 			else
 
- 			{
 
- 				link = *first_pair;
 
- 				while (link->next != NULL)
 
- 				{
 
- 					link = link->next;
 
- 				}
 
- 				link->next = pair;
 
- 			}
 
- 			mode = PARSE_MODE_NAME;
 
- 			break;
 
- 		    default:
 
- 			mode = PARSE_MODE_NAME;
 
- 			break;
 
- 		}
 
- 	}
 
- #endif
 
- 	return 0;
 
- }
 
- /** Translate an av_pair into two strings
 
-  *
 
-  * @param rh a handle to parsed configuration.
 
-  * @param pair a pointer to a VALUE_PAIR structure.
 
-  * @param name the name of the pair.
 
-  * @param ln the size of name.
 
-  * @param value the value of the pair.
 
-  * @param lv the size of value.
 
-  * @return 0 on success, -1 on failure.
 
-  */
 
- int rc_avpair_tostr (rc_handle const *rh, VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
 
- {
 
- #if 0  
 
- 	DICT_VALUE     *dval;
 
- 	char            buffer[32];
 
- 	struct in_addr  inad;
 
- 	unsigned char  *ptr;
 
- 	unsigned int    pos;
 
- 	*name = *value = '\0';
 
- 	if (!pair || pair->name[0] == '\0') {
 
- 		rc_log(LOG_ERR, "rc_avpair_tostr: pair is NULL or empty");
 
- 		return -1;
 
- 	}
 
- 	strlcpy(name, pair->name, (size_t) ln);
 
- 	switch (pair->type)
 
- 	{
 
- 	    case PW_TYPE_STRING:
 
- 	    	lv--;
 
- 	    	pos = 0;
 
- 		ptr = (unsigned char *) pair->strvalue;
 
- 		if (pair->attribute == PW_DIGEST_ATTRIBUTES) {
 
- 			pair->strvalue[*(ptr + 1)] = '\0';
 
- 			ptr += 2;
 
- 		}
 
- 		while (*ptr != '\0')
 
- 		{
 
- 			if (!(isprint (*ptr)))
 
- 			{
 
- 				if (lv >= 4) {
 
- 					snprintf (&value[pos], lv, "\\%03o", *ptr);
 
- 					pos += 4;
 
- 					lv -= 4;
 
- 				} else {
 
- 					break;
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				if (lv > 0) {
 
- 					value[pos++] = *ptr;
 
- 					lv--;
 
- 				} else {
 
- 					break;
 
- 				}
 
- 			}
 
- 			ptr++;
 
- 		}
 
- 		if (lv > 0)
 
- 			value[pos++] = 0;
 
- 		else
 
- 			value[pos-1] = 0;
 
- 		break;
 
- 	    case PW_TYPE_INTEGER:
 
- 		dval = rc_dict_getval (rh, pair->lvalue, pair->name);
 
- 		if (dval != NULL)
 
- 		{
 
- 			strlcpy(value, dval->name, (size_t) lv);
 
- 		}
 
- 		else
 
- 		{
 
- 			snprintf(value, lv, "%ld", (long int)pair->lvalue);
 
- 		}
 
- 		break;
 
- 	    case PW_TYPE_IPADDR:
 
- 		inad.s_addr = htonl(pair->lvalue);
 
- 		strlcpy (value, inet_ntoa (inad), (size_t) lv);
 
- 		break;
 
- 	    case PW_TYPE_IPV6ADDR:
 
- 	    	if (inet_ntop(AF_INET6, pair->strvalue, value, lv) == NULL)
 
- 	    		return -1;
 
- 		break;
 
- 	    case PW_TYPE_IPV6PREFIX: {
 
- 	    	uint8_t ip[16];
 
- 	    	char txt[48];
 
- 	    	if (pair->lvalue < 2)
 
- 	    		return -1;
 
- 	    	memset(ip, 0, sizeof(ip));
 
- 	    	memcpy(ip, pair->strvalue+2, pair->lvalue-2);
 
- 	    	if (inet_ntop(AF_INET6, ip, txt, sizeof(txt)) == NULL)
 
- 	    		return -1;
 
- 		snprintf(value, lv, "%s/%u", txt, (unsigned)pair->strvalue[1]);
 
- 		break;
 
- 	    }
 
- 	    case PW_TYPE_DATE:
 
- 		strftime (value, lv, "%m/%d/%y %H:%M:%S",
 
- 			  gmtime ((time_t *) & pair->lvalue));
 
- 		break;
 
- 	    default:
 
- 		rc_log(LOG_ERR, "rc_avpair_tostr: unknown attribute type %d", pair->type);
 
- 		return -1;
 
- 		break;
 
- 	}
 
- #endif
 
- 	return 0;
 
- }
 
- /** Format a sequence of attribute value pairs into a printable string
 
-  *
 
-  * The caller should provide a storage buffer and the buffer length.
 
-  *
 
-  * @param rh a handle to parsed configuration.
 
-  * @param pair a pointer to a #VALUE_PAIR structure.
 
-  * @param buf will hold the string output of the pair.
 
-  * @param len the size of buf.
 
-  * @return a pointer to provided storage buffer.
 
-  */
 
- char *rc_avpair_log(rc_handle const *rh, VALUE_PAIR *pair, char *buf, size_t buf_len)
 
- {
 
- #if 0  
 
- 	size_t len, nlen;
 
- 	VALUE_PAIR *vp;
 
- 	char name[33], value[256];
 
- 	len = 0;
 
- 	for (vp = pair; vp != NULL; vp = vp->next) {
 
- 		if (rc_avpair_tostr(rh, vp, name, sizeof(name), value,
 
- 		    sizeof(value)) == -1)
 
- 		        return NULL;
 
- 		nlen = len + 32 + 3 + strlen(value) + 2 + 2;
 
- 		if(nlen<buf_len-1) {
 
- 			sprintf(buf + len, "%-32s = '%s'\n", name, value);
 
- 		} else return buf;
 
- 		len = nlen - 1;
 
- 	}
 
- #endif    
 
- 	return buf;
 
- }
 
- #if 0
 
- /** Get a sequence of attribute value pairs from the file input and make them into a list of value_pairs
 
-  *
 
-  * @param rh a handle to parsed configuration.
 
-  * @param input a %FILE handle.
 
-  * @return the array of value pairs.
 
-  */
 
- VALUE_PAIR *rc_avpair_readin(rc_handle const *rh, FILE *input)
 
- {
 
- 	VALUE_PAIR *vp = NULL;
 
- 	char buffer[1024], *q;
 
- 	while (fgets(buffer, sizeof(buffer), input) != NULL)
 
- 	{
 
- 		q = buffer;
 
- 		while(*q && isspace(*q)) q++;
 
- 		if ((*q == '\n') || (*q == '#') || (*q == '\0'))
 
- 			continue;
 
- 		if (rc_avpair_parse(rh, q, &vp) < 0) {
 
- 			rc_log(LOG_ERR, "rc_avpair_readin: malformed attribute: %s", buffer);
 
- 			rc_avpair_free(vp);
 
- 			return NULL;
 
- 		}
 
- 	}
 
- 	return vp;
 
- }
 
- #endif
 
 
  |