Fixed libradius.h, and src/lib.
Updated some modules to call dict_addattr() according to new API
#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
typedef struct dict_value {
unsigned int attr;
+ unsigned int vendor;
int value;
char name[1];
} DICT_VALUE;
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 *);
* 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);
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);
/*
* 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
/*
/*
* 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) {
}
/*
- * 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;
}
* 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 */
/*
* 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;
}
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;
}
}
* 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;
* 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;
/*
* 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));
/*
* 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);
}
/*
* 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;
* First, look up aliases.
*/
dval.attr = attr;
+ dval.vendor = vendor;
dval.name[0] = '\0';
/*
/*
* 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];
my_dv = (DICT_VALUE *) buffer;
my_dv->attr = attr;
+ my_dv->vendor = vendor;
my_dv->name[0] = '\0';
/*
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 {
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 {
"<`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;
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;
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;
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;
* 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;
/*
* Ignore non-wire attributes
*/
- if ((VENDOR(reply->attribute) == 0) &&
+ if ((reply->vendor == 0) &&
((reply->attribute & 0xFFFF) > 0xff)) {
#ifndef NDEBUG
/*
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);
}
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;
}
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;
}
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;
}
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;
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;
*/
{
DICT_VALUE *dval;
- dval = dict_valbyattr(vp->attribute,
+ dval = dict_valbyattr(vp->attribute, vp->vendor,
vp->vp_integer);
if (dval) {
strlcpy(vp->vp_strvalue,
* 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)
{
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;
}
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)
* 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 {
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;
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;
}
/*
* 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);
}
switch (vsa_llen) {
case 0:
- attribute = (myvendor << 16) | myattr;
+ attribute = myattr;
ptr += 4 + vsa_tlen;
attrlen -= (4 + vsa_tlen);
packet_length -= 4 + vsa_tlen;
default: /* can't hit this. */
return -1;
}
- attribute |= (vendorcode << 16);
vsa_ptr = ptr;
ptr += vsa_tlen;
* 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
* 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);
(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");
* 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;
/*
* 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;
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;
}
/*
* 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;
}
/*
* 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 {
/*
* 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;
last = &first;
while (vp) {
- if (attr >= 0 && vp->attribute != attr) {
+ if ((attr >= 0) &&
+ (vp->attribute != attr) && (vp->vendor != vendor)) {
vp = vp->next;
continue;
}
*/
VALUE_PAIR *paircopy(VALUE_PAIR *vp)
{
- return paircopy2(vp, -1);
+ return paircopy2(vp, -1, 0);
}
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) {
/*
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
memcpy(found, i, sizeof(*found));
found->next = mynext;
- pairdelete(&found->next, found->attribute);
+ pairdelete(&found->next, found->attribute, found->vendor);
/*
* 'tailto' may have been
/*
* 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;
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;
}
* 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;
}
* 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;
}
}
- 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;
}
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;
*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;
*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;
* 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);
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;
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.
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...
*/
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",
}
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",
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);
* 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
* ('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){
}
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",