]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Restructure how attributes are packed
authorAlan T. DeKok <aland@freeradius.org>
Thu, 27 Dec 2012 17:09:10 +0000 (12:09 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 27 Dec 2012 17:09:10 +0000 (12:09 -0500)
so that we can potentially allow TLVs in the standard space

src/include/libradius.h
src/include/radius.h
src/lib/dict.c
src/lib/print.c
src/lib/radius.c
src/lib/valuepair.c

index 41c50db456b65271c75f4b0f8034d071b6ea9045..8ac5f77f0d6da64d9f24c544af86cfdbb15c244a 100644 (file)
@@ -276,7 +276,7 @@ void                vp_printlist(FILE *, const VALUE_PAIR *);
  */
 int            str2argv(char *str, char **argv, int max_argc);
 int            dict_str2oid(const char *ptr, unsigned int *pattr,
-                            int vendor, int tlv_depth);
+                            unsigned int *pvendor, int tlv_depth);
 int            dict_addvendor(const char *name, unsigned int value);
 int            dict_addattr(const char *name, int attr, unsigned int vendor, int type, ATTR_FLAGS flags);
 int            dict_addvalue(const char *namestr, const char *attrstr, int value);
index 02842b2e73427ff7519c5142a95f1e956a7645c4..c7a48161e93f0f45bf4484478cd1100921b32bd1 100644 (file)
 #define VENDORPEC_MICROSOFT            311
 #define VENDORPEC_FREERADIUS           11344
 #define VENDORPEC_WIMAX                        24757
-#define VENDORPEC_EXTENDED             (1 << 25)
 
 /*
  * Vendor specific attributes
index d6fdea239855873c838c67dd937e3e7e24f43c9b..ced5101858e4e73855b251802c011396d74589d6 100644 (file)
@@ -114,12 +114,24 @@ const FR_NAME_NUMBER dict_attr_types[] = {
 
 
 /*
- *     WiMAX craziness.
+ *     For packing multiple TLV numbers into one 32-bit integer.  The
+ *     first 3 bytes are just the 8-bit number.  The next two are
+ *     more limited.  We only allow 31 attributes nested 3 layers
+ *     deep, and only 7 nested 4 layers deep.  This should be
+ *     sufficient for most purposes.
+ *
+ *     For TLVs and extended attributes, we packet the base attribute
+ *     number into the upper 8 bits of the "vendor" field.
+ *
+ *     e.g.    OID             attribute       vendor
+ *             241.1           1               (241 << 8)
+ *             241.26.9.1      1               (241 << 8) | (9)
+ *             241.1.2         1 | (2 << 8)    (241 << 8)
  */
 #define MAX_TLV_NEST (4)
 /*
  *     Bit packing:
- *     8 bits of base VSA
+ *     8 bits of base attribute
  *     8 bits for nested TLV 1
  *     8 bits for nested TLV 2
  *     5 bits for nested TLV 3
@@ -468,7 +480,7 @@ int dict_addvendor(const char *name, unsigned int value)
        size_t length;
        DICT_VENDOR *dv;
 
-       if (value > FR_MAX_VENDOR) {
+       if (value >= FR_MAX_VENDOR) {
                fr_strerror_printf("dict_addvendor: Cannot handle vendor ID larger than 2^24");
                return -1;
        }
@@ -612,7 +624,8 @@ int dict_addattr(const char *name, int attr, unsigned int vendor, int type,
                        return -1;
                }
 
-               if (vendor) {   /* VSAs cannot be of format EVS */
+               /* VSAs cannot be of format EVS */
+               if ((vendor & (FR_MAX_VENDOR - 1)) != 0) {
                        fr_strerror_printf("dict_addattr: Attribute of type \"evs\" fails internal sanity check");
                        return -1;
                }
@@ -628,7 +641,7 @@ int dict_addattr(const char *name, int attr, unsigned int vendor, int type,
                return -1;
        }
 
-       if (vendor) {
+       if ((vendor & (FR_MAX_VENDOR -1)) != 0) {
                DICT_VENDOR *dv;
                static DICT_VENDOR *last_vendor = NULL;
 
@@ -669,7 +682,7 @@ int dict_addattr(const char *name, int attr, unsigned int vendor, int type,
                 */
                if (!dv) {
                        fr_strerror_printf("dict_addattr: Unknown vendor %u",
-                                          vendor);
+                                          vendor & (FR_MAX_VENDOR - 1));
                        return -1;
                }
 
@@ -683,22 +696,46 @@ int dict_addattr(const char *name, int attr, unsigned int vendor, int type,
                } /* else 256..65535 are allowed */
 
                /*
-                *      Set the extended flags as appropriate.
+                *      If the attribute is in the standard space, AND
+                *      has a sub-type (e.g. 241.1 or 255.3), then its
+                *      number is placed into the upper 8 bits of the
+                *      vendor field.
+                *
+                *      This also happens for the new VSAs.
+                *
+                *      If we find it, then set the various flags
+                *      based on what we see.
                 */
-               if (vendor > FR_MAX_VENDOR) {
-                       unsigned int myattr;
+               if (vendor >= FR_MAX_VENDOR) {
+                       unsigned int parent;
 
-                       myattr = (vendor >> 24) & 0xff;
-                       myattr |= PW_VENDOR_SPECIFIC << 8;
+                       parent = (vendor / FR_MAX_VENDOR) & 0xff;
 
-                       da = dict_attrbyvalue(myattr, VENDORPEC_EXTENDED);
+                       da = dict_attrbyvalue(parent, 0);
                        if (!da) {
-                               fr_strerror_printf("dict_addattr: ATTRIBUTE refers to unknown \"evs\" type.");
+                               fr_strerror_printf("dict_addattr: ATTRIBUTE refers to unknown parent attribute %u.", parent);
                                return -1;
                        }
+
+                       /*
+                        *      These flags are inhereited inherited
+                        *      from the parent.
+                        */
                        flags.extended = da->flags.extended;
                        flags.long_extended = da->flags.long_extended;
-                       flags.evs = da->flags.evs;
+
+                       /*
+                        *      Non-extended attributes can't have VSAs.
+                        */
+                       if (!flags.extended &&
+                           ((vendor & (FR_MAX_VENDOR - 1)) != 0)) {
+                               fr_strerror_printf("dict_addattr: ATTRIBUTE cannot be a VSA");
+                               return -1;
+                       }
+
+                       if ((vendor & (FR_MAX_VENDOR - 1)) != 0) {
+                               flags.evs = 1;
+                       }
                }
 
                /*
@@ -711,15 +748,6 @@ int dict_addattr(const char *name, int attr, unsigned int vendor, int type,
                flags.wimax = dv->flags;
        }
 
-       /*
-        *      If it's an attribute in the standard space, with the
-        *      "extended" format flag set, then set the vendor ID to
-        *      "extended".
-        */
-       if (!vendor && flags.extended) {
-               vendor = VENDORPEC_EXTENDED;
-       }
-
        /*
         *      Create a new attribute for the list
         */
@@ -979,43 +1007,119 @@ static int sscanf_i(const char *str, unsigned int *pvalue)
 }
 
 
-int dict_str2oid(const char *ptr, unsigned int *pvalue, int vendor, int tlv_depth)
+/*
+ *     Get the OID based on various pieces of information.
+ *
+ *     Remember, the packing format is weird.
+ *
+ *     00VID   000000AA        normal VSA for vendor VID
+ *     00VID   AABBCCDD        normal VSAs with TLVs
+ *     EE000   000000AA        extended attr (241.1)
+ *     EE000   AABBCCDD        extended attr with TLVs
+ *     EEVID   000000AA        EVS with vendor VID, attr AAA
+ *     EEVID   AABBCCDD        EVS with TLVs
+ *
+ *     <whew>!  Are we crazy, or what?
+ */
+int dict_str2oid(const char *ptr, unsigned int *pvalue, unsigned int *pvendor,
+                int tlv_depth)
 {
        const char *p;
        unsigned int value;
        DICT_ATTR *da;
 
        if (tlv_depth > fr_attr_max_tlv) {
-               fr_strerror_printf("Attribute has too long OID");
-               return 0;
+               fr_strerror_printf("Too many sub-attributes");
+               return -1;
        }
 
+       /*
+        *      If *pvalue is set, check if the attribute exists.
+        *      Otherwise, check that the vendor exists.
+        */
        if (*pvalue) {
-               if (vendor) {
-                       da = dict_attrbyvalue(*pvalue, vendor);
-               } else {
-                       da = dict_attrbyvalue(*pvalue, VENDORPEC_EXTENDED);
-               }
+               da = dict_attrbyvalue(*pvalue, *pvendor);
                if (!da) {
                        fr_strerror_printf("Parent attribute is undefined.");
-                       return 0;
+                       return -1;
                }
-       
-               if (!(da->flags.has_tlv || da->flags.extended || da->flags.long_extended)) {
-                       fr_strerror_printf("Parent attribute %s cannot have sub-tlvs",
+               
+               if (!da->flags.has_tlv && !da->flags.extended) {
+                       fr_strerror_printf("Parent attribute %s cannot have sub-attributes",
                                           da->name);
-                       return 0;
+                       return -1;
+               }
+
+       } else if ((*pvendor & (FR_MAX_VENDOR - 1)) != 0) {
+               if (!dict_vendorbyvalue(*pvendor & (FR_MAX_VENDOR - 1))) {
+                       fr_strerror_printf("Unknown vendor %u",
+                                          *pvendor & (FR_MAX_VENDOR - 1));
+                       return -1;
                }
        }
 
        p = strchr(ptr, '.');
 
+       /*
+        *      Look for 26.VID.x.y
+        *
+        *      If we find it, re-write the parameters, and recurse.
+        */
+       if (!*pvendor && (tlv_depth == 0) && (*pvalue == PW_VENDOR_SPECIFIC)) {
+               const DICT_VENDOR *dv;
+
+               if (!p) {
+                       fr_strerror_printf("VSA needs to have sub-attribute");
+                       return -1;
+               }
+
+               if (!sscanf_i(ptr, pvendor)) {
+                       fr_strerror_printf("Invalid number in attribute");
+                       return -1;
+               }
+
+               if (*pvendor >= FR_MAX_VENDOR) {
+                       fr_strerror_printf("Cannot handle vendor ID larger than 2^24");
+                       
+                       return -1;
+               }
+
+               dv = dict_vendorbyvalue(*pvendor & (FR_MAX_VENDOR - 1));
+               if (!dv) {
+                       fr_strerror_printf("Unknown vendor \"%u\" ",
+                                          *pvendor  & (FR_MAX_VENDOR - 1));
+                       return -1;
+               }
+
+               /*
+                *      Start off with (attr=0, vendor=VID), and
+                *      recurse.  This causes the various checks above
+                *      to be done.
+                */
+               *pvalue = 0;
+               return dict_str2oid(p + 1, pvalue, pvendor, 0);
+       }
+
        if (!sscanf_i(ptr, &value)) {
-               fr_strerror_printf("Failed parsing attribute identifier %s",
-                                  ptr);
-               return 0;
+               fr_strerror_printf("Invalid number in attribute");
+               return -1;
+       }
+
+       if (!*pvendor && (tlv_depth == 1) &&
+           (da->flags.has_tlv || da->flags.extended)) {
+
+
+               *pvendor = *pvalue * FR_MAX_VENDOR;
+               *pvalue = value;
+
+               if (!p) return 0;
+               return dict_str2oid(p + 1, pvalue, pvendor, 1);
        }
 
+       /*
+        *      And pack the data according to the scheme described in
+        *      the comments at the start of this function.
+        */
        if (*pvalue) {
                *pvalue |= (value & fr_attr_mask[tlv_depth]) << fr_attr_shift[tlv_depth];
        } else {
@@ -1023,18 +1127,34 @@ int dict_str2oid(const char *ptr, unsigned int *pvalue, int vendor, int tlv_dept
        }
 
        if (p) {
-               return dict_str2oid(p + 1, pvalue, vendor, tlv_depth + 1);
+               return dict_str2oid(p + 1, pvalue, pvendor, tlv_depth + 1);
        }
 
        return tlv_depth;
 }
 
+/*
+ *     Bamboo skewers under the fingernails in 5, 4, 3, 2, ...
+ */
+static DICT_ATTR *dict_parent(unsigned int attr, unsigned int vendor)
+{
+       if (vendor < FR_MAX_VENDOR) {
+               return dict_attrbyvalue(attr & 0xff, vendor);
+       }
+
+       if (attr < 256) {
+               return dict_attrbyvalue((vendor / FR_MAX_VENDOR) & 0xff, 0);
+       }
+
+       return dict_attrbyvalue(attr & 0xff, vendor);
+}
+
 
 /*
  *     Process the ATTRIBUTE command
  */
 static int process_attribute(const char* fn, const int line,
-                            const unsigned int block_vendor, DICT_ATTR *block_tlv,
+                            unsigned int block_vendor, DICT_ATTR *block_tlv,
                             int tlv_depth, char **argv, int argc)
 {
        int             oid = 0;
@@ -1051,6 +1171,9 @@ static int process_attribute(const char* fn, const int line,
                return -1;
        }
 
+       /*
+        *      Dictionaries need to have real names, not shitty ones.
+        */
        if (strncmp(argv[1], "Attr-", 5) == 0) {
                fr_strerror_printf("dict_init: %s[%d]: Invalid attribute name",
                                   fn, line);
@@ -1060,13 +1183,10 @@ static int process_attribute(const char* fn, const int line,
        memset(&flags, 0, sizeof(flags));
 
        /*
-        *      Look for extended attributes before doing anything else.
+        *      Look for OIDs before doing anything else.
         */
        p = strchr(argv[1], '.');
-       if (p) {
-               *p = '\0';
-               oid = 1;
-       }
+       if (p) oid = 1;
 
        /*
         *      Validate all entries
@@ -1076,71 +1196,15 @@ static int process_attribute(const char* fn, const int line,
                return -1;
        }
 
-       if (!p) {
-               if (value > (1 << 24)) {
-                       fr_strerror_printf("dict_init: %s[%d]: Attribute number is too large", fn, line);
-                       return -1;
-               }
-
-               
-               /*
-                *      Parse NUM.NUM.NUM.NUM
-                */
-       } else {
-               int my_depth;
+       if (oid) {
                DICT_ATTR *da;
 
-               *p = '.';       /* reset for later printing */
-
-               if (block_vendor) {
-                       da = dict_attrbyvalue(value, block_vendor);
-               } else if (value == PW_VENDOR_SPECIFIC) {
-                       char *q;
-                       const DICT_VENDOR *dv;
-
-                       p++;
-                       q = strchr(p, '.');
-                       if (!q) {
-                       invalid:
-                               fr_strerror_printf("dict_init: %s[%d]: Invalid attribute identifier", fn, line);
-                               return -1;
-                       }
-                       *q = '\0';
-
-                       if (!sscanf_i(p, &vendor)) {
-                               *q = '.';
-                               goto invalid;
-                       }
-                       *(q++) = '.';
-                       p = q;
-                       dv = dict_vendorbyvalue(vendor);
-                       if (!dv) {
-                               fr_strerror_printf("dict_init: %s[%d]: Unknown vendor \"%u\" in attribute identifier", fn, line, vendor);
-                               return -1;
-                       }
-
-                       argv[1] = p;
-                       return process_attribute(fn, line, vendor, NULL, 0,
-                                                argv, argc);
-               } else {
-                       da = dict_attrbyvalue(value, VENDORPEC_EXTENDED);
-               }
-               if (!da) {
-                       fr_strerror_printf("dict_init: %s[%d]: Entry refers to unknown attribute %d", fn, line, value);
-                       return -1;
-               }
+               vendor = block_vendor;
 
                /*
-                *      241.1 means 241 is of type "extended".
-                *      Otherwise, die.
+                *      Parse the rest of the OID.
                 */
-               if (!(da->flags.has_tlv || da->flags.extended || da->flags.long_extended)) {
-                       fr_strerror_printf("dict_init: %s[%d]: Parent attribute %s cannot contain sub-attributes", fn, line, da->name);
-                       return -1;
-               }
-
-               my_depth = dict_str2oid(p + 1, &value, block_vendor, tlv_depth + 1);
-               if (!my_depth) {
+               if (dict_str2oid(p + 1, &value, &vendor, tlv_depth + 1) < 0) {
                        char buffer[256];
 
                        strlcpy(buffer, fr_strerror(), sizeof(buffer));
@@ -1148,25 +1212,17 @@ static int process_attribute(const char* fn, const int line,
                        fr_strerror_printf("dict_init: %s[%d]: Invalid attribute identifier: %s", fn, line, buffer);
                        return -1;
                }
+               block_vendor = vendor;
 
                /*
-                *      Look up the REAL parent TLV.
+                *      Set the flags based on the parents flags.
                 */
-               if (my_depth > 1) {
-                       unsigned int parent = value;
-
-                       parent &= ~(fr_attr_mask[my_depth] << fr_attr_shift[my_depth]);
-
-                       da = dict_attrbyvalue(parent, da->vendor);
-                       if (!da) {
-                               fr_strerror_printf("dict_init: %s[%d]: Parent attribute is undefined.", fn, line);
-                               return -1;
-                       }
+               da = dict_parent(value, vendor);
+               if (!da) {
+                       fr_strerror_printf("dict_init: %s[%d]: Parent attribute is undefined.", fn, line);
+                       return -1;
                }
-               
-               /*
-                *      Set which type of attribute this is.
-                */
+
                flags.extended = da->flags.extended;
                flags.long_extended = da->flags.long_extended;
                flags.evs = da->flags.evs;
@@ -1269,7 +1325,7 @@ static int process_attribute(const char* fn, const int line,
                        type = PW_TYPE_OCTETS;
                        flags.extended = 1;
                        flags.evs = 1;
-                       if (((value >> fr_attr_shift[1]) & fr_attr_mask[1]) != PW_VENDOR_SPECIFIC) {
+                       if (value != PW_VENDOR_SPECIFIC) {
                                fr_strerror_printf("dict_init: %s[%d]: Attributes of type \"evs\" MUST have attribute code 26.", fn, line);
                                return -1;
                        }
@@ -1287,7 +1343,7 @@ static int process_attribute(const char* fn, const int line,
                /*
                 *      Keep it real.
                 */
-               if (flags.extended || flags.long_extended || flags.evs) {
+               if (flags.extended) {
                        fr_strerror_printf("dict_init: %s[%d]: Extended attributes cannot use flags", fn, line);
                        return -1;
                }
@@ -2031,6 +2087,8 @@ static int my_dict_init(const char *dir, const char *fn,
 
                        /*
                         *      Check for extended attr VSAs
+                        *
+                        *      BEGIN-VENDOR foo format=Foo-Encapsulation-Attr
                         */
                        if (argc > 2) {
                                if (strncmp(argv[2], "format=", 7) != 0) {
@@ -2058,11 +2116,11 @@ static int my_dict_init(const char *dir, const char *fn,
                                }
                                
                                /*
-                                *      Pack the encapsulating attribute
-                                *      into the vendor Id.  This attribute
-                                *      MUST be >= 241.
+                                *      Pack the encapsulating
+                                *      attribute into the upper 8
+                                *      bits of the vendor ID
                                 */
-                               block_vendor |= (da->attr & fr_attr_mask[1]) * FR_MAX_VENDOR;
+                               block_vendor |= (da->attr & fr_attr_mask[0]) * FR_MAX_VENDOR;
                        }
 
                        continue;
index 5865d8ea91621aac07938a02e3b5516f29c50440..3f9772463cbfd4cd767fd297f8c58c86820236be 100644 (file)
@@ -545,6 +545,9 @@ static size_t vp_print_attr_oid(char *buffer, size_t size, unsigned int attr,
        return outlen;
 }
 
+/*
+ *     Handle attributes which are not in the dictionaries.
+ */
 size_t vp_print_name(char *buffer, size_t bufsize,
                     unsigned int attr, unsigned int vendor)
 {
@@ -558,23 +561,23 @@ size_t vp_print_name(char *buffer, size_t bufsize,
        p += len;
        bufsize -= len;
 
-       if (vendor && (vendor != VENDORPEC_EXTENDED)) {
-               DICT_VENDOR *dv;
+       if (vendor > FR_MAX_VENDOR) {
+               len = snprintf(p, bufsize, "%u.",
+                              vendor / FR_MAX_VENDOR);
+               p += len;
+               bufsize -= len;
+               vendor &= (FR_MAX_VENDOR) - 1;
+       }
 
-               if (vendor >= FR_MAX_VENDOR) {
-                       len = snprintf(p, bufsize, "%u.",
-                                      vendor / FR_MAX_VENDOR);
-                       p += len;
-                       bufsize -= len;
-                       vendor &= (FR_MAX_VENDOR) - 1;
-               }
+       if (vendor) {
+               DICT_VENDOR *dv;
 
                dv = dict_vendorbyvalue(vendor);
                if (dv) {
                        dv_type = dv->type;
                }
                len = snprintf(p, bufsize, "26.%u.", vendor);
-
+               
                p += len;
                bufsize -= len;
        }
index df1481c6b437030b635d66c762595dc5b4664060..35f4a5501efdf30bd7531f916d18fb123ff546e8 100644 (file)
@@ -1078,28 +1078,31 @@ int rad_vp2extended(const RADIUS_PACKET *packet,
 {
        int len;
        int hdr_len;
-       int nest = 1;
        uint8_t *start = ptr;
        const VALUE_PAIR *vp = *pvp;
 
-       if (vp->vendor < VENDORPEC_EXTENDED) {
+       if (!vp->flags.extended) {
                fr_strerror_printf("rad_vp2extended called for non-extended attribute");
                return -1;
        }
 
-       if (room < 3) return 0;
-
-       ptr[0] = vp->attribute & 0xff;
-       ptr[1] = 3;
+       /*
+        *      The attribute number is encoded into the upper 8 bits
+        *      of the vendor ID.
+        */
+       ptr[0] = (vp->vendor / FR_MAX_VENDOR) & 0xff;
 
-       if (vp->flags.extended) {
-               ptr[2] = (vp->attribute & 0xff00) >> 8;
+       if (!vp->flags.long_extended) {
+               if (room < 3) return 0;
+       
+               ptr[1] = 3;
+               ptr[2] = vp->attribute & fr_attr_mask[0];
 
-       } else if (vp->flags.long_extended) {
+       } else {
                if (room < 4) return 0;
 
                ptr[1] = 4;
-               ptr[2] = (vp->attribute & 0xff00) >> 8;
+               ptr[2] = vp->attribute & fr_attr_mask[0];
                ptr[3] = 0;
        }
 
@@ -1119,27 +1122,19 @@ int rad_vp2extended(const RADIUS_PACKET *packet,
 
                if (room < (size_t) (ptr[1] + 5)) return 0;
 
-               /*
-                *      RADIUS Attribute Type is packed into the high byte
-                *      of the Vendor Id.  So over-write it in the packet.
-                *
-                *      And hard-code Extended-Type to Vendor-Specific.
-                */
-               ptr[0] = (vp->vendor >> 24) & 0xff;
                ptr[2] = 26;
 
                evs[0] = 0;     /* always zero */
                evs[1] = (vp->vendor >> 16) & 0xff;
                evs[2] = (vp->vendor >> 8) & 0xff;
                evs[3] = vp->vendor & 0xff;
-               evs[4] = vp->attribute & 0xff;          
+               evs[4] = vp->attribute & fr_attr_mask[0];               
 
                ptr[1] += 5;
-               nest = 0;
        }
        hdr_len = ptr[1];
 
-       len = vp2data_any(packet, original, secret, nest,
+       len = vp2data_any(packet, original, secret, 0,
                          pvp, ptr + ptr[1], room - hdr_len);
        if (len <= 0) return len;
 
@@ -3704,9 +3699,8 @@ ssize_t rad_attr2vp_extended(const RADIUS_PACKET *packet,
                             VALUE_PAIR **pvp)
 {
        unsigned int attribute;
-       int shift = 1;
        int continued = 0;
-       unsigned int vendor = VENDORPEC_EXTENDED;
+       unsigned int vendor = 0;
        size_t data_len = length;
        const uint8_t *data;
        DICT_ATTR *da;
@@ -3718,9 +3712,8 @@ ssize_t rad_attr2vp_extended(const RADIUS_PACKET *packet,
                return -1;
        }
 
-       da = dict_attrbyvalue(data[0], vendor);
-       if (!da ||
-           (!da->flags.extended && !da->flags.long_extended)) {
+       da = dict_attrbyvalue(data[0], 0);
+       if (!da || !da->flags.extended) {
                fr_strerror_printf("rad_attr2vp_extended: Attribute is not extended format");
                return -1;
        }
@@ -3742,14 +3735,12 @@ ssize_t rad_attr2vp_extended(const RADIUS_PACKET *packet,
         *      The attribute is "241.1", for example.  Go look that
         *      up to see what type it is.
         */
-       attribute = data[0];
-       attribute |= (data[2] << fr_attr_shift[1]);
+       vendor = data[0] * FR_MAX_VENDOR;
+       attribute = data[2];
 
        da = dict_attrbyvalue(attribute, vendor);
        if (!da) goto raw;
 
-       vendor = VENDORPEC_EXTENDED;
-
        data_len = length;
        if (data[1] < length) data_len = data[1];
 
@@ -3782,16 +3773,9 @@ ssize_t rad_attr2vp_extended(const RADIUS_PACKET *packet,
                 */
                if (data[0] != 0) goto raw;
                
-               vendor = ((data[1] << 16) |
-                         (data[2] << 8) |
-                         data[3]);
-               
-               /*
-                *      Pack the *encapsulating* attribute number into
-                *      the vendor id.  This number should be >= 241.
-                */
-               vendor |= start[0] * FR_MAX_VENDOR;
-               shift = 0;
+               vendor |= ((data[1] << 16) |
+                          (data[2] << 8) |
+                          data[3]);
                
                /*
                 *      Over-write the attribute with the
@@ -3806,20 +3790,20 @@ ssize_t rad_attr2vp_extended(const RADIUS_PACKET *packet,
                int first_offset = 4;
                ssize_t my_len;
 
-               if (vendor != VENDORPEC_EXTENDED) first_offset += 5;
+               if (da->flags.evs) first_offset += 5;
 
                my_len = extended_attrlen(start, start + length);
                if (my_len < 0) goto raw;
 
-               if (vendor != VENDORPEC_EXTENDED) my_len -= 5;
+               if (da->flags.evs) my_len -= 5;
 
                return data2vp_continued(packet, original, secret,
-                                        start, length, pvp, shift,
+                                        start, length, pvp, 0,
                                         attribute, vendor,
                                         first_offset, 4, my_len);
        }
 
-       if (data2vp_any(packet, original, secret, shift,
+       if (data2vp_any(packet, original, secret, 0,
                        attribute, vendor, data, data_len, pvp) < 0) {
                return -1;
        }
@@ -3859,6 +3843,8 @@ ssize_t rad_attr2vp(const RADIUS_PACKET *packet,
                    const uint8_t *data, size_t length,
                    VALUE_PAIR **pvp)
 {
+       DICT_ATTR *da;
+
        if ((length < 2) || (data[1] < 2) || (data[1] > length)) {
                fr_strerror_printf("rad_attr2vp: Insufficient data");
                return -1;
@@ -3875,7 +3861,8 @@ ssize_t rad_attr2vp(const RADIUS_PACKET *packet,
        /*
         *      Extended attribute format gets their own handler.
         */
-       if (dict_attrbyvalue(data[0], VENDORPEC_EXTENDED) != NULL) {
+       da = dict_attrbyvalue(data[0], 0);
+       if (da && da->flags.extended) {
                return rad_attr2vp_extended(packet, original, secret,
                                            data, length, pvp);
        }
index db6580fd3edf6e9ff0b8676cc19dc602189efc9e..77735d422213b70841412728d17c3e0ff2d93f11 100644 (file)
@@ -1536,7 +1536,7 @@ static VALUE_PAIR *pairmake_any(const char *attribute, const char *value,
        if (attr >= (unsigned) (1 << (dv_type << 3))) goto invalid;
 
        if (*p == '.') {
-               if (!dict_str2oid(p + 1, &attr, vendor, 1)) {
+               if (dict_str2oid(p + 1, &attr, &vendor, 1) < 0) {
                        return NULL;
                }
        }