From e541966c4ad2c79bed09a868acca0d46ad5be6d8 Mon Sep 17 00:00:00 2001 From: "Alan T. DeKok" Date: Mon, 5 Oct 2009 10:51:16 +0200 Subject: [PATCH] Moved API to (attr, vendor), instead of just attr Fixed libradius.h, and src/lib. Updated some modules to call dict_addattr() according to new API --- src/include/libradius.h | 27 +++++------ src/include/radius.h | 15 +++--- src/lib/dict.c | 73 +++++++++++++++-------------- src/lib/print.c | 10 ++-- src/lib/radius.c | 70 +++++++++++++++------------ src/lib/valuepair.c | 51 ++++++++++---------- src/lib/vqp.c | 14 +++--- src/modules/rlm_checkval/rlm_checkval.c | 2 +- src/modules/rlm_counter/rlm_counter.c | 2 +- src/modules/rlm_ldap/rlm_ldap.c | 8 ++-- src/modules/rlm_sqlcounter/rlm_sqlcounter.c | 2 +- 11 files changed, 140 insertions(+), 134 deletions(-) diff --git a/src/include/libradius.h b/src/include/libradius.h index f7d1abd..07b0193 100644 --- a/src/include/libradius.h +++ b/src/include/libradius.h @@ -63,8 +63,6 @@ RCSIDH(libradius_h, "$Id$") #define CHAP_VALUE_LENGTH 16 #define MAX_STRING_LEN 254 /* RFC2138: string 0-253 octets */ -# define VENDOR(x) ((x >> 16) & 0xffff) - #ifdef _LIBRADIUS # define AUTH_HDR_LEN 20 # define VENDORPEC_USR 429 @@ -128,6 +126,7 @@ typedef struct dict_attr { typedef struct dict_value { unsigned int attr; + unsigned int vendor; int value; char name[1]; } DICT_VALUE; @@ -238,7 +237,7 @@ void fr_print_string(const char *in, size_t inlen, char *out, size_t outlen); int vp_prints_value(char *out, size_t outlen, VALUE_PAIR *vp, int delimitst); -const char *vp_print_name(char *buffer, size_t bufsize, int attr); +const char *vp_print_name(char *buffer, size_t bufsize, int attr, int vendor); int vp_prints(char *out, size_t outlen, VALUE_PAIR *vp); void vp_print(FILE *, VALUE_PAIR *); void vp_printlist(FILE *, VALUE_PAIR *); @@ -248,14 +247,14 @@ void vp_printlist(FILE *, VALUE_PAIR *); * Dictionary functions. */ int dict_addvendor(const char *name, int value); -int dict_addattr(const char *name, int vendor, int type, int value, ATTR_FLAGS flags); +int dict_addattr(const char *name, int attr, int vendor, int type, ATTR_FLAGS flags); int dict_addvalue(const char *namestr, const char *attrstr, int value); int dict_init(const char *dir, const char *fn); void dict_free(void); -DICT_ATTR *dict_attrbyvalue(unsigned int attr); +DICT_ATTR *dict_attrbyvalue(unsigned int attr, unsigned int vendor); DICT_ATTR *dict_attrbyname(const char *attr); -DICT_VALUE *dict_valbyattr(unsigned int attr, int val); -DICT_VALUE *dict_valbyname(unsigned int attr, const char *val); +DICT_VALUE *dict_valbyattr(unsigned int attr, unsigned int vendor, int val); +DICT_VALUE *dict_valbyname(unsigned int attr, unsigned int vendor, const char *val); int dict_vendorbyname(const char *name); DICT_VENDOR *dict_vendorbyvalue(int vendor); @@ -322,27 +321,27 @@ int rad_tunnel_pwdecode(uint8_t *encpw, size_t *len, int rad_chap_encode(RADIUS_PACKET *packet, uint8_t *output, int id, VALUE_PAIR *password); VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *original, - const char *secret, int attribute, int length, - const uint8_t *data); + const char *secret, int attribute, int vendor, + int length, const uint8_t *data); int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original, const char *secret, const VALUE_PAIR *vp, uint8_t *ptr); /* valuepair.c */ VALUE_PAIR *pairalloc(DICT_ATTR *da); -VALUE_PAIR *paircreate(int attr, int type); +VALUE_PAIR *paircreate(int attr, int vendor, int type); void pairfree(VALUE_PAIR **); void pairbasicfree(VALUE_PAIR *pair); -VALUE_PAIR *pairfind(VALUE_PAIR *, int); -void pairdelete(VALUE_PAIR **, int); +VALUE_PAIR *pairfind(VALUE_PAIR *, int attr, int vendor); +void pairdelete(VALUE_PAIR **, int attr, int vendor); void pairadd(VALUE_PAIR **, VALUE_PAIR *); void pairreplace(VALUE_PAIR **first, VALUE_PAIR *add); int paircmp(VALUE_PAIR *check, VALUE_PAIR *data); VALUE_PAIR *paircopyvp(const VALUE_PAIR *vp); VALUE_PAIR *paircopy(VALUE_PAIR *vp); -VALUE_PAIR *paircopy2(VALUE_PAIR *vp, int attr); +VALUE_PAIR *paircopy2(VALUE_PAIR *vp, int attr, int vendor); void pairmove(VALUE_PAIR **to, VALUE_PAIR **from); -void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, int attr); +void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, int attr, int vendor); VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value); VALUE_PAIR *pairmake(const char *attribute, const char *value, int operator); VALUE_PAIR *pairread(const char **ptr, FR_TOKEN *eol); diff --git a/src/include/radius.h b/src/include/radius.h index c7946a9..a8be5d3 100644 --- a/src/include/radius.h +++ b/src/include/radius.h @@ -298,22 +298,23 @@ /* * Vendor Private Enterprise Codes */ +#define VENDORPEC_MICROSOFT 311 #define VENDORPEC_FREERADIUS 11344 - +#define VENDORPEC_WIMAX 24757 /* * Vendor specific attributes */ -#define PW_FREERADIUS_PROXIED_TO ((VENDORPEC_FREERADIUS<<16)|1) +#define PW_FREERADIUS_PROXIED_TO 1 /* * Microsoft has vendor code 311. */ -#define PW_MSCHAP_RESPONSE ((311 << 16) | 1) -#define PW_MSCHAP_ERROR ((311 << 16) | 2) -#define PW_MSCHAP_CHALLENGE ((311 << 16) | 11) -#define PW_MSCHAP2_RESPONSE ((311 << 16) | 25) -#define PW_MSCHAP2_SUCCESS ((311 << 16) | 26) +#define PW_MSCHAP_RESPONSE 1 +#define PW_MSCHAP_ERROR 2 +#define PW_MSCHAP_CHALLENGE 11 +#define PW_MSCHAP2_RESPONSE 25 +#define PW_MSCHAP2_SUCCESS 26 /* diff --git a/src/lib/dict.c b/src/lib/dict.c index 3fbd110..a08c67b 100644 --- a/src/lib/dict.c +++ b/src/lib/dict.c @@ -481,12 +481,12 @@ int dict_addvendor(const char *name, int value) /* * Add an attribute to the dictionary. */ -int dict_addattr(const char *name, int vendor, int type, int value, +int dict_addattr(const char *name, int attr, int vendor, int type, ATTR_FLAGS flags) { size_t namelen; static int max_attr = 0; - DICT_ATTR *attr; + DICT_ATTR *da; namelen = strlen(name); if (namelen >= DICT_ATTR_MAX_NAME_LEN) { @@ -495,33 +495,33 @@ int dict_addattr(const char *name, int vendor, int type, int value, } /* - * If the value is '-1', that means use a pre-existing + * If the attr is '-1', that means use a pre-existing * one (if it already exists). If one does NOT already exist, * then create a new attribute, with a non-conflicting value, * and use that. */ - if (value == -1) { + if (attr == -1) { if (dict_attrbyname(name)) { return 0; /* exists, don't add it again */ } - value = ++max_attr; + attr = ++max_attr; } else if (vendor == 0) { /* * Update 'max_attr' */ - if (value > max_attr) { - max_attr = value; + if (attr > max_attr) { + max_attr = attr; } } - if (value < 0) { + if (attr < 0) { fr_strerror_printf("dict_addattr: ATTRIBUTE has invalid number (less than zero)"); return -1; } - if (value >= 65536) { + if (attr >= 65536) { fr_strerror_printf("dict_addattr: ATTRIBUTE has invalid number (larger than 65535)."); return -1; } @@ -575,7 +575,7 @@ int dict_addattr(const char *name, int vendor, int type, int value, * FIXME: Switch over dv->type, and limit things * properly. */ - if ((dv->type == 1) && (value >= 256) && !flags.is_tlv) { + if ((dv->type == 1) && (attr >= 256) && !flags.is_tlv) { fr_strerror_printf("dict_addattr: ATTRIBUTE has invalid number (larger than 255)."); return -1; } /* else 256..65535 are allowed */ @@ -584,35 +584,34 @@ int dict_addattr(const char *name, int vendor, int type, int value, /* * Create a new attribute for the list */ - if ((attr = fr_pool_alloc(sizeof(*attr) + namelen)) == NULL) { + if ((da = fr_pool_alloc(sizeof(*da) + namelen)) == NULL) { fr_strerror_printf("dict_addattr: out of memory"); return -1; } - memcpy(attr->name, name, namelen); - attr->name[namelen] = '\0'; - attr->attr = value; - attr->attr |= (vendor << 16); /* FIXME: hack */ - attr->vendor = vendor; - attr->type = type; - attr->flags = flags; - attr->vendor = vendor; + memcpy(da->name, name, namelen); + da->name[namelen] = '\0'; + da->attr = attr; + da->vendor = vendor; + da->type = type; + da->flags = flags; + da->vendor = vendor; /* * Insert the attribute, only if it's not a duplicate. */ - if (!fr_hash_table_insert(attributes_byname, attr)) { + if (!fr_hash_table_insert(attributes_byname, da)) { DICT_ATTR *a; /* * If the attribute has identical number, then * ignore the duplicate. */ - a = fr_hash_table_finddata(attributes_byname, attr); - if (a && (strcasecmp(a->name, attr->name) == 0)) { - if (a->attr != attr->attr) { + a = fr_hash_table_finddata(attributes_byname, da); + if (a && (strcasecmp(a->name, da->name) == 0)) { + if (a->attr != da->attr) { fr_strerror_printf("dict_addattr: Duplicate attribute name %s", name); - fr_pool_free(attr); + fr_pool_free(da); return -1; } @@ -627,9 +626,9 @@ int dict_addattr(const char *name, int vendor, int type, int value, fr_hash_table_delete(attributes_byvalue, a); - if (!fr_hash_table_replace(attributes_byname, attr)) { + if (!fr_hash_table_replace(attributes_byname, da)) { fr_strerror_printf("dict_addattr: Internal error storing attribute %s", name); - fr_pool_free(attr); + fr_pool_free(da); return -1; } } @@ -643,13 +642,13 @@ int dict_addattr(const char *name, int vendor, int type, int value, * files, but when we're printing them, (and looking up * by value) we want to use the NEW name. */ - if (!fr_hash_table_replace(attributes_byvalue, attr)) { + if (!fr_hash_table_replace(attributes_byvalue, da)) { fr_strerror_printf("dict_addattr: Failed inserting attribute name %s", name); return -1; } - if (!vendor && (value > 0) && (value < 256)) { - dict_base_attrs[value] = attr; + if (!vendor && (attr > 0) && (attr < 256)) { + dict_base_attrs[attr] = da; } return 0; @@ -783,7 +782,7 @@ int dict_addvalue(const char *namestr, const char *attrstr, int value) * name and value. There are lots in * dictionary.ascend. */ - old = dict_valbyname(dattr->attr, namestr); + old = dict_valbyname(dattr->attr, dattr->vendor, namestr); if (old && (old->value == dval->value)) { fr_pool_free(dval); return 0; @@ -996,7 +995,7 @@ static int process_attribute(const char* fn, const int line, /* * Add it in. */ - if (dict_addattr(argv[0], vendor, type, value, flags) < 0) { + if (dict_addattr(argv[0], value, vendor, type, flags) < 0) { char buffer[256]; strlcpy(buffer, fr_strerror(), sizeof(buffer)); @@ -1738,14 +1737,14 @@ int dict_init(const char *dir, const char *fn) /* * Get an attribute by its numerical value. */ -DICT_ATTR *dict_attrbyvalue(unsigned int attr) +DICT_ATTR *dict_attrbyvalue(unsigned int attr, unsigned int vendor) { DICT_ATTR dattr; - if ((attr > 0) && (attr < 256)) return dict_base_attrs[attr]; + if ((attr > 0) && (attr < 256) && !vendor) return dict_base_attrs[attr]; dattr.attr = attr; - dattr.vendor = VENDOR(attr); + dattr.vendor = vendor; return fr_hash_table_finddata(attributes_byvalue, &dattr); } @@ -1769,7 +1768,7 @@ DICT_ATTR *dict_attrbyname(const char *name) /* * Associate a value with an attribute and return it. */ -DICT_VALUE *dict_valbyattr(unsigned int attr, int value) +DICT_VALUE *dict_valbyattr(unsigned int attr, unsigned int vendor, int value) { DICT_VALUE dval, *dv; @@ -1777,6 +1776,7 @@ DICT_VALUE *dict_valbyattr(unsigned int attr, int value) * First, look up aliases. */ dval.attr = attr; + dval.vendor = vendor; dval.name[0] = '\0'; /* @@ -1794,7 +1794,7 @@ DICT_VALUE *dict_valbyattr(unsigned int attr, int value) /* * Get a value by its name, keyed off of an attribute. */ -DICT_VALUE *dict_valbyname(unsigned int attr, const char *name) +DICT_VALUE *dict_valbyname(unsigned int attr, unsigned int vendor, const char *name) { DICT_VALUE *my_dv, *dv; uint32_t buffer[(sizeof(*my_dv) + DICT_VALUE_MAX_NAME_LEN + 3)/4]; @@ -1803,6 +1803,7 @@ DICT_VALUE *dict_valbyname(unsigned int attr, const char *name) my_dv = (DICT_VALUE *) buffer; my_dv->attr = attr; + my_dv->vendor = vendor; my_dv->name[0] = '\0'; /* diff --git a/src/lib/print.c b/src/lib/print.c index e122a74..9b51cbb 100644 --- a/src/lib/print.c +++ b/src/lib/print.c @@ -241,7 +241,7 @@ int vp_prints_value(char * out, size_t outlen, VALUE_PAIR *vp, int delimitst) case PW_TYPE_INTEGER: if ( vp->flags.has_tag ) { /* Attribute value has a tag, need to ignore it */ - if ((v = dict_valbyattr(vp->attribute, (vp->vp_integer & 0xffffff))) + if ((v = dict_valbyattr(vp->attribute, vp->vendor, (vp->vp_integer & 0xffffff))) != NULL) a = v->name; else { @@ -252,7 +252,7 @@ int vp_prints_value(char * out, size_t outlen, VALUE_PAIR *vp, int delimitst) case PW_TYPE_BYTE: case PW_TYPE_SHORT: /* Normal, non-tagged attribute */ - if ((v = dict_valbyattr(vp->attribute, vp->vp_integer)) + if ((v = dict_valbyattr(vp->attribute, vp->vendor, vp->vp_integer)) != NULL) a = v->name; else { @@ -385,14 +385,12 @@ static const char *vp_tokens[] = { "<`STRING`>" }; -const char *vp_print_name(char *buffer, size_t bufsize, int attr) +const char *vp_print_name(char *buffer, size_t bufsize, int attr, int vendor) { - int vendor; size_t len = 0; if (!buffer) return NULL; - vendor = VENDOR(attr); if (vendor) { DICT_VENDOR *v; @@ -436,7 +434,7 @@ int vp_prints(char *out, size_t outlen, VALUE_PAIR *vp) len = 0; if (!name || !*name) { - if (!vp_print_name(namebuf, sizeof(namebuf), vp->attribute)) { + if (!vp_print_name(namebuf, sizeof(namebuf), vp->attribute, vp->attribute)) { return 0; } name = namebuf; diff --git a/src/lib/radius.c b/src/lib/radius.c index 5333303..7109bf1 100644 --- a/src/lib/radius.c +++ b/src/lib/radius.c @@ -800,7 +800,7 @@ static VALUE_PAIR *rad_vp2tlv(VALUE_PAIR *vps) attribute = vps->attribute & 0xffff00ff; maxattr = vps->attribute & 0x0ff; - tlv = paircreate(attribute, PW_TYPE_TLV); + tlv = paircreate(attribute, vps->vendor, PW_TYPE_TLV); if (!tlv) return NULL; tlv->length = 0; @@ -812,6 +812,7 @@ static VALUE_PAIR *rad_vp2tlv(VALUE_PAIR *vps) if (!vp->flags.is_tlv || vp->flags.encoded || (vp->flags.encrypt != FLAG_ENCRYPT_NONE) || + (vp->vendor != vps->vendor) || ((vp->attribute & 0xffff00ff) != attribute) || ((vp->attribute & 0x0000ff00) <= maxattr)) { break; @@ -963,8 +964,8 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original, * For interoperability, always put vendor attributes * into their own VSA. */ - if ((vendorcode = VENDOR(vp->attribute)) == 0) { - *(ptr++) = vp->attribute & 0xFF; + if ((vendorcode = vp->vendor) == 0) { + *(ptr++) = vp->attribute & 0xff; length_ptr = ptr; *(ptr++) = 2; total_length += 2; @@ -1223,7 +1224,7 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original, /* * Ignore non-wire attributes */ - if ((VENDOR(reply->attribute) == 0) && + if ((reply->vendor == 0) && ((reply->attribute & 0xFFFF) > 0xff)) { #ifndef NDEBUG /* @@ -1495,7 +1496,7 @@ int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original, packet->dst_port); for (reply = packet->vps; reply; reply = reply->next) { - if ((VENDOR(reply->attribute) == 0) && + if ((reply->vendor == 0) && ((reply->attribute & 0xFFFF) > 0xff)) continue; debug_pair(reply); } @@ -1635,7 +1636,7 @@ int rad_packet_ok(RADIUS_PACKET *packet, int flags) inet_ntop(packet->src_ipaddr.af, &packet->src_ipaddr.ipaddr, host_ipaddr, sizeof(host_ipaddr)), - packet->data_len, AUTH_HDR_LEN); + (int) packet->data_len, AUTH_HDR_LEN); return 0; } @@ -1649,7 +1650,7 @@ int rad_packet_ok(RADIUS_PACKET *packet, int flags) inet_ntop(packet->src_ipaddr.af, &packet->src_ipaddr.ipaddr, host_ipaddr, sizeof(host_ipaddr)), - packet->data_len, MAX_PACKET_LEN); + (int) packet->data_len, MAX_PACKET_LEN); return 0; } @@ -1735,7 +1736,7 @@ int rad_packet_ok(RADIUS_PACKET *packet, int flags) inet_ntop(packet->src_ipaddr.af, &packet->src_ipaddr.ipaddr, host_ipaddr, sizeof(host_ipaddr)), - packet->data_len, totallen); + (int) packet->data_len, totallen); return 0; } @@ -1995,7 +1996,8 @@ RADIUS_PACKET *rad_recv(int fd, int flags) packet->src_port, packet->code); } - DEBUG(", id=%d, length=%d\n", packet->id, packet->data_len); + DEBUG(", id=%d, length=%d\n", + packet->id, (int) packet->data_len); } return packet; @@ -2175,8 +2177,7 @@ int rad_verify(RADIUS_PACKET *packet, RADIUS_PACKET *original, static VALUE_PAIR *data2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *original, - const char *secret, - UNUSED unsigned int attribute, size_t length, + const char *secret, size_t length, const uint8_t *data, VALUE_PAIR *vp) { int offset = 0; @@ -2306,7 +2307,7 @@ static VALUE_PAIR *data2vp(const RADIUS_PACKET *packet, */ { DICT_VALUE *dval; - dval = dict_valbyattr(vp->attribute, + dval = dict_valbyattr(vp->attribute, vp->vendor, vp->vp_integer); if (dval) { strlcpy(vp->vp_strvalue, @@ -2464,8 +2465,8 @@ static void rad_sortvp(VALUE_PAIR **head) * Sane clients should put the fragments next to each other, in * which case this is O(N), in the number of fragments. */ -static uint8_t *rad_coalesce(unsigned int attribute, size_t length, - uint8_t *data, +static uint8_t *rad_coalesce(unsigned int attribute, int vendor, + size_t length, uint8_t *data, size_t packet_length, size_t *ptlv_length) { @@ -2476,9 +2477,12 @@ static uint8_t *rad_coalesce(unsigned int attribute, size_t length, for (ptr = data + length; ptr != (data + packet_length); ptr += ptr[1]) { + /* FIXME: Check that there are 6 bytes of data here... */ if ((ptr[0] != PW_VENDOR_SPECIFIC) || (ptr[1] < (2 + 4 + 3)) || /* WiMAX VSA with continuation */ - (ptr[2] != 0) || (ptr[3] != 0)) { /* our requirement */ + (ptr[2] != 0) || (ptr[3] != 0) || /* our requirement */ + (ptr[4] != ((vendor >> 8) & 0xff)) || + (ptr[5] != (vendor & 0xff))) { continue; } @@ -2551,6 +2555,7 @@ static uint8_t *rad_coalesce(unsigned int attribute, size_t length, static VALUE_PAIR *rad_continuation2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *original, const char *secret, int attribute, + int vendor, int length, /* CANNOT be zero */ uint8_t *data, size_t packet_length, int flag, DICT_ATTR *da) @@ -2565,7 +2570,7 @@ static VALUE_PAIR *rad_continuation2vp(const RADIUS_PACKET *packet, * multiple attributes. */ if (flag) { - tlv_data = rad_coalesce(attribute, length, + tlv_data = rad_coalesce(attribute, vendor, length, data, packet_length, &tlv_length); if (!tlv_data) return NULL; } else { @@ -2592,7 +2597,7 @@ static VALUE_PAIR *rad_continuation2vp(const RADIUS_PACKET *packet, memcpy(tlv_data, data, tlv_length); } - vp = paircreate(attribute, PW_TYPE_OCTETS); + vp = paircreate(attribute, vendor, PW_TYPE_OCTETS); if (!vp) return NULL; vp->type = PW_TYPE_TLV; @@ -2629,14 +2634,14 @@ static VALUE_PAIR *rad_continuation2vp(const RADIUS_PACKET *packet, for (ptr = tlv_data; ptr != (tlv_data + tlv_length); ptr += ptr[1]) { - vp = paircreate(attribute | (ptr[0] << 8), PW_TYPE_OCTETS); + vp = paircreate(attribute | (ptr[0] << 8), vendor, PW_TYPE_OCTETS); if (!vp) { pairfree(&head); goto not_well_formed; } if (!data2vp(packet, original, secret, - ptr[0], ptr[1] - 2, ptr + 2, vp)) { + ptr[1] - 2, ptr + 2, vp)) { pairfree(&head); goto not_well_formed; } @@ -2659,16 +2664,17 @@ static VALUE_PAIR *rad_continuation2vp(const RADIUS_PACKET *packet, /* * Parse a RADIUS attribute into a data structure. */ -VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, const RADIUS_PACKET *original, - const char *secret, int attribute, int length, - const uint8_t *data) +VALUE_PAIR *rad_attr2vp(const RADIUS_PACKET *packet, + const RADIUS_PACKET *original, + const char *secret, int attribute, int vendor, + int length, const uint8_t *data) { VALUE_PAIR *vp; - vp = paircreate(attribute, PW_TYPE_OCTETS); + vp = paircreate(attribute, vendor, PW_TYPE_OCTETS); if (!vp) return NULL; - return data2vp(packet, original, secret, attribute, length, data, vp); + return data2vp(packet, original, secret, length, data, vp); } @@ -2842,7 +2848,7 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, switch (vsa_llen) { case 0: - attribute = (myvendor << 16) | myattr; + attribute = myattr; ptr += 4 + vsa_tlen; attrlen -= (4 + vsa_tlen); packet_length -= 4 + vsa_tlen; @@ -2911,7 +2917,6 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, default: /* can't hit this. */ return -1; } - attribute |= (vendorcode << 16); vsa_ptr = ptr; ptr += vsa_tlen; @@ -2943,12 +2948,14 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, * are a secret flag to us that the attribute has * already been dealt with. */ - if (attribute == 0x60b50000) goto next; + if ((vendorcode == VENDORPEC_WIMAX) && (attribute == 0)) { + goto next; + } if (vsa_offset) { DICT_ATTR *da; - da = dict_attrbyvalue(attribute); + da = dict_attrbyvalue(attribute, vendorcode); /* * If it's NOT continued, AND we know @@ -2963,7 +2970,8 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, * Go do a lot of work to find the stuff. */ pair = rad_continuation2vp(packet, original, secret, - attribute, attrlen, ptr, + attribute, vendorcode, + attrlen, ptr, packet_length, ((vsa_ptr[2] & 0x80) != 0), da); @@ -2985,7 +2993,7 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original, (attribute != PW_CHARGEABLE_USER_IDENTITY)) goto next; pair = rad_attr2vp(packet, original, secret, - attribute, attrlen, ptr); + attribute, vendorcode, attrlen, ptr); if (!pair) { pairfree(&packet->vps); fr_strerror_printf("out of memory"); @@ -3407,7 +3415,7 @@ int rad_chap_encode(RADIUS_PACKET *packet, uint8_t *output, int id, * Use Chap-Challenge pair if present, * Request-Authenticator otherwise. */ - challenge = pairfind(packet->vps, PW_CHAP_CHALLENGE); + challenge = pairfind(packet->vps, PW_CHAP_CHALLENGE, 0); if (challenge) { memcpy(ptr, challenge->vp_strvalue, challenge->length); i += challenge->length; diff --git a/src/lib/valuepair.c b/src/lib/valuepair.c index 8cdf673..350fb35 100644 --- a/src/lib/valuepair.c +++ b/src/lib/valuepair.c @@ -138,12 +138,12 @@ VALUE_PAIR *pairalloc(DICT_ATTR *da) /* * Create a new valuepair. */ -VALUE_PAIR *paircreate(int attr, int type) +VALUE_PAIR *paircreate(int attr, int vendor, int type) { VALUE_PAIR *vp; DICT_ATTR *da; - da = dict_attrbyvalue(attr); + da = dict_attrbyvalue(attr, vendor); if ((vp = pairalloc(da)) == NULL) { fr_strerror_printf("out of memory"); return NULL; @@ -156,12 +156,12 @@ VALUE_PAIR *paircreate(int attr, int type) if (!da) { char *p = (char *) (vp + 1); - vp->vendor = VENDOR(attr); + vp->vendor = vendor; vp->attribute = attr; vp->name = p; vp->type = type; /* be forgiving */ - if (!vp_print_name(p, FR_VP_NAME_LEN, vp->attribute)) { + if (!vp_print_name(p, FR_VP_NAME_LEN, attr, vendor)) { free(vp); return NULL; } @@ -206,9 +206,9 @@ void pairfree(VALUE_PAIR **pair_ptr) /* * Find the pair with the matching attribute */ -VALUE_PAIR * pairfind(VALUE_PAIR *first, int attr) +VALUE_PAIR * pairfind(VALUE_PAIR *first, int attr, int vendor) { - while(first && first->attribute != attr) + while(first && (first->attribute != attr) && (first->vendor != vendor)) first = first->next; return first; } @@ -217,14 +217,14 @@ VALUE_PAIR * pairfind(VALUE_PAIR *first, int attr) /* * Delete the pair(s) with the matching attribute */ -void pairdelete(VALUE_PAIR **first, int attr) +void pairdelete(VALUE_PAIR **first, int attr, int vendor) { VALUE_PAIR *i, *next; VALUE_PAIR **last = first; for(i = *first; i; i = next) { next = i->next; - if (i->attribute == attr) { + if ((i->attribute == attr) && (i->vendor == vendor)) { *last = next; pairbasicfree(i); } else { @@ -335,7 +335,7 @@ VALUE_PAIR *paircopyvp(const VALUE_PAIR *vp) /* * Copy just a certain type of pairs. */ -VALUE_PAIR *paircopy2(VALUE_PAIR *vp, int attr) +VALUE_PAIR *paircopy2(VALUE_PAIR *vp, int attr, int vendor) { VALUE_PAIR *first, *n, **last; @@ -343,7 +343,8 @@ VALUE_PAIR *paircopy2(VALUE_PAIR *vp, int attr) last = &first; while (vp) { - if (attr >= 0 && vp->attribute != attr) { + if ((attr >= 0) && + (vp->attribute != attr) && (vp->vendor != vendor)) { vp = vp->next; continue; } @@ -363,7 +364,7 @@ VALUE_PAIR *paircopy2(VALUE_PAIR *vp, int attr) */ VALUE_PAIR *paircopy(VALUE_PAIR *vp) { - return paircopy2(vp, -1); + return paircopy2(vp, -1, 0); } @@ -438,7 +439,7 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from) if (i->attribute == PW_FALL_THROUGH || (i->attribute != PW_HINT && i->attribute != PW_FRAMED_ROUTE)) { - found = pairfind(*to, i->attribute); + found = pairfind(*to, i->attribute, i->vendor); switch (i->operator) { /* @@ -450,7 +451,7 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from) if (!i->vp_strvalue[0] || (strcmp((char *)found->vp_strvalue, (char *)i->vp_strvalue) == 0)){ - pairdelete(to, found->attribute); + pairdelete(to, found->attribute, found->vendor); /* * 'tailto' may have been @@ -545,7 +546,7 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from) memcpy(found, i, sizeof(*found)); found->next = mynext; - pairdelete(&found->next, found->attribute); + pairdelete(&found->next, found->attribute, found->vendor); /* * 'tailto' may have been @@ -591,7 +592,7 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from) /* * Move one kind of attributes from one list to the other */ -void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, int attr) +void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, int attr, int vendor) { VALUE_PAIR *to_tail, *i, *next; VALUE_PAIR *iprev = NULL; @@ -609,13 +610,13 @@ void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, int attr) 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. + * vendor=0, attr = PW_VENDOR_SPECIFIC means + * "match any vendor attribute". Otherwise, do + * an exact match */ - if ((attr != PW_VENDOR_SPECIFIC) && - (i->attribute != attr)) { + if (((vendor != 0) || (attr != PW_VENDOR_SPECIFIC)) && + (i->attribute != attr) && (i->vendor != vendor)) { iprev = i; continue; } @@ -624,8 +625,8 @@ void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, int attr) * If the attribute to move IS a VSA, then it ignores * any non-VSA attribute. */ - if ((attr == PW_VENDOR_SPECIFIC) && - (VENDOR(i->attribute) == 0)) { + if ((vendor == 0) && (attr == PW_VENDOR_SPECIFIC) && + (i->vendor == 0)) { iprev = i; continue; } @@ -1008,7 +1009,7 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value) * Look for the named value for the given * attribute. */ - if ((dval = dict_valbyname(vp->attribute, value)) == NULL) { + if ((dval = dict_valbyname(vp->attribute, vp->vendor, value)) == NULL) { fr_strerror_printf("Unknown value %s for attribute %s", value, vp->name); return NULL; @@ -1357,14 +1358,12 @@ static VALUE_PAIR *pairmake_any(const char *attribute, const char *value, } } - attr |= vendor << 16; - /* * We've now parsed the attribute properly, Let's create * it. This next stop also looks the attribute up in the * dictionary, and creates the appropriate type for it. */ - if ((vp = paircreate(attr, PW_TYPE_OCTETS)) == NULL) { + if ((vp = paircreate(attr, vendor, PW_TYPE_OCTETS)) == NULL) { fr_strerror_printf("out of memory"); return NULL; } diff --git a/src/lib/vqp.c b/src/lib/vqp.c index ed5ceca..8dec957 100644 --- a/src/lib/vqp.c +++ b/src/lib/vqp.c @@ -435,7 +435,7 @@ int vqp_decode(RADIUS_PACKET *packet) tail = &packet->vps; - vp = paircreate(PW_VQP_PACKET_TYPE, PW_TYPE_OCTETS); + vp = paircreate(PW_VQP_PACKET_TYPE, 0, PW_TYPE_OCTETS); if (!vp) { fr_strerror_printf("No memory"); return -1; @@ -446,7 +446,7 @@ int vqp_decode(RADIUS_PACKET *packet) *tail = vp; tail = &(vp->next); - vp = paircreate(PW_VQP_ERROR_CODE, PW_TYPE_OCTETS); + vp = paircreate(PW_VQP_ERROR_CODE, 0, PW_TYPE_OCTETS); if (!vp) { fr_strerror_printf("No memory"); return -1; @@ -457,7 +457,7 @@ int vqp_decode(RADIUS_PACKET *packet) *tail = vp; tail = &(vp->next); - vp = paircreate(PW_VQP_SEQUENCE_NUMBER, PW_TYPE_OCTETS); + vp = paircreate(PW_VQP_SEQUENCE_NUMBER, 0, PW_TYPE_OCTETS); if (!vp) { fr_strerror_printf("No memory"); return -1; @@ -485,7 +485,7 @@ int vqp_decode(RADIUS_PACKET *packet) * Hack to get the dictionaries to work correctly. */ attribute |= 0x2000; - vp = paircreate(attribute, PW_TYPE_OCTETS); + vp = paircreate(attribute, 0, PW_TYPE_OCTETS); if (!vp) { pairfree(&packet->vps); @@ -556,7 +556,7 @@ int vqp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original) if (packet->data) return 0; - vp = pairfind(packet->vps, PW_VQP_PACKET_TYPE); + vp = pairfind(packet->vps, PW_VQP_PACKET_TYPE, 0); if (!vp) { fr_strerror_printf("Failed to find VQP-Packet-Type in response packet"); return -1; @@ -571,7 +571,7 @@ int vqp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original) length = VQP_HDR_LEN; memset(vps, 0, sizeof(vps)); - vp = pairfind(packet->vps, PW_VQP_ERROR_CODE); + vp = pairfind(packet->vps, PW_VQP_ERROR_CODE, 0); /* * FIXME: Map attributes from calling-station-Id, etc. @@ -586,7 +586,7 @@ int vqp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original) if (!vp) for (i = 0; i < VQP_MAX_ATTRIBUTES; i++) { if (!contents[code][i]) break; - vps[i] = pairfind(packet->vps, contents[code][i] | 0x2000); + vps[i] = pairfind(packet->vps, contents[code][i] | 0x2000, 0); /* * FIXME: Print the name... diff --git a/src/modules/rlm_checkval/rlm_checkval.c b/src/modules/rlm_checkval/rlm_checkval.c index 8728621..535727a 100644 --- a/src/modules/rlm_checkval/rlm_checkval.c +++ b/src/modules/rlm_checkval/rlm_checkval.c @@ -160,7 +160,7 @@ static int checkval_instantiate(CONF_SECTION *conf, void **instance) */ memset(&flags, 0, sizeof(flags)); - dict_addattr(data->check_name, 0, PW_TYPE_STRING, -1,flags); + dict_addattr(data->check_name, -1, 0, PW_TYPE_STRING, flags); dattr = dict_attrbyname(data->check_name); if (!dattr){ radlog(L_ERR, "rlm_checkval: No such attribute %s", diff --git a/src/modules/rlm_counter/rlm_counter.c b/src/modules/rlm_counter/rlm_counter.c index 45c70f6..31de4e1 100644 --- a/src/modules/rlm_counter/rlm_counter.c +++ b/src/modules/rlm_counter/rlm_counter.c @@ -413,7 +413,7 @@ static int counter_instantiate(CONF_SECTION *conf, void **instance) } memset(&flags, 0, sizeof(flags)); - dict_addattr(data->counter_name, 0, PW_TYPE_INTEGER, -1, flags); + dict_addattr(data->counter_name, -1, 0, PW_TYPE_INTEGER, flags); dattr = dict_attrbyname(data->counter_name); if (dattr == NULL) { radlog(L_ERR, "rlm_counter: Failed to create counter attribute %s", diff --git a/src/modules/rlm_ldap/rlm_ldap.c b/src/modules/rlm_ldap/rlm_ldap.c index 7cdb1a4..37dba13 100644 --- a/src/modules/rlm_ldap/rlm_ldap.c +++ b/src/modules/rlm_ldap/rlm_ldap.c @@ -456,7 +456,7 @@ ldap_instantiate(CONF_SECTION * conf, void **instance) group_name = rad_malloc((strlen(xlat_name) + 1 + 11) * sizeof(char)); sprintf(group_name,"%s-Ldap-Group",xlat_name); DEBUG("rlm_ldap: Creating new attribute %s",group_name); - dict_addattr(group_name, 0, PW_TYPE_STRING, -1, flags); + dict_addattr(group_name, -1, 0, PW_TYPE_STRING, flags); dattr = dict_attrbyname(group_name); if (dattr == NULL){ radlog(L_ERR, "rlm_ldap: Failed to create attribute %s",group_name); @@ -504,7 +504,7 @@ ldap_instantiate(CONF_SECTION * conf, void **instance) * instance 'V1' of the LDAP module has processed this * request. */ - dict_addattr("LDAP-Instance", 0, PW_TYPE_STRING, -1, flags); + dict_addattr("LDAP-Instance", -1, 0, PW_TYPE_STRING, flags); /* * ('eDir-APC', '1') in config items list @@ -516,11 +516,11 @@ ldap_instantiate(CONF_SECTION * conf, void **instance) * ('eDir-APC', '3') in config items list * eDirectory APC has been completed */ - dict_addattr("eDir-APC", 0, PW_TYPE_STRING, -1, flags); + dict_addattr("eDir-APC", -1, 0, PW_TYPE_STRING, flags); /* * eDir-Auth-Option allows for a different NMAS Authentication method to be used instead of password */ - dict_addattr("eDir-Auth-Option", 0, PW_TYPE_STRING, -1, flags); + dict_addattr("eDir-Auth-Option", -1, 0, PW_TYPE_STRING, flags); #endif if (inst->num_conns <= 0){ diff --git a/src/modules/rlm_sqlcounter/rlm_sqlcounter.c b/src/modules/rlm_sqlcounter/rlm_sqlcounter.c index e6a75e6..960dde8 100644 --- a/src/modules/rlm_sqlcounter/rlm_sqlcounter.c +++ b/src/modules/rlm_sqlcounter/rlm_sqlcounter.c @@ -528,7 +528,7 @@ static int sqlcounter_instantiate(CONF_SECTION *conf, void **instance) } memset(&flags, 0, sizeof(flags)); - dict_addattr(data->counter_name, 0, PW_TYPE_INTEGER, -1, flags); + dict_addattr(data->counter_name, -1, 0, PW_TYPE_INTEGER, flags); dattr = dict_attrbyname(data->counter_name); if (dattr == NULL) { radlog(L_ERR, "rlm_sqlcounter: Failed to create counter attribute %s", -- 2.1.4