Moved API to (attr, vendor), instead of just attr
authorAlan T. DeKok <aland@freeradius.org>
Mon, 5 Oct 2009 08:51:16 +0000 (10:51 +0200)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 31 May 2010 08:16:14 +0000 (10:16 +0200)
Fixed libradius.h, and src/lib.

Updated some modules to call dict_addattr() according to new API

src/include/libradius.h
src/include/radius.h
src/lib/dict.c
src/lib/print.c
src/lib/radius.c
src/lib/valuepair.c
src/lib/vqp.c
src/modules/rlm_checkval/rlm_checkval.c
src/modules/rlm_counter/rlm_counter.c
src/modules/rlm_ldap/rlm_ldap.c
src/modules/rlm_sqlcounter/rlm_sqlcounter.c

index f7d1abd..07b0193 100644 (file)
@@ -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);
index c7946a9..a8be5d3 100644 (file)
 /*
  *  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
 
 
 /*
index 3fbd110..a08c67b 100644 (file)
@@ -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';
 
        /*
index e122a74..9b51cbb 100644 (file)
@@ -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;
index 5333303..7109bf1 100644 (file)
@@ -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;
index 8cdf673..350fb35 100644 (file)
@@ -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;
        }
index ed5ceca..8dec957 100644 (file)
@@ -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...
index 8728621..535727a 100644 (file)
@@ -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",
index 45c70f6..31de4e1 100644 (file)
@@ -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",
index 7cdb1a4..37dba13 100644 (file)
@@ -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){
index e6a75e6..960dde8 100644 (file)
@@ -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",