From: Arran Cudbard-Bell Date: Fri, 23 Feb 2018 03:11:21 +0000 (+0600) Subject: Get vendor number by looking it up in the attribute hierarchy X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=454af26591936b2d2b89b935e2f3cf0bef04b07b;p=thirdparty%2Ffreeradius-server.git Get vendor number by looking it up in the attribute hierarchy This is cleanup work that should have been done a while back. Vendors are now represented in the dictionary hierarchy, so having a vendor field in attributes is superfluous. --- diff --git a/src/include/dict.h b/src/include/dict.h index e7b3cbf7ef8..f4e2fa9ce03 100644 --- a/src/include/dict.h +++ b/src/include/dict.h @@ -88,7 +88,6 @@ extern fr_dict_t *fr_dict_internal; /** Dictionary attribute */ struct dict_attr { - unsigned int vendor; //!< Vendor that defines this attribute. unsigned int attr; //!< Attribute number. fr_type_t type; //!< Value type. @@ -229,12 +228,50 @@ ssize_t fr_dict_attr_by_oid(fr_dict_t *dict, fr_dict_attr_t const **parent, /* * Lookup */ + +/** Return true if this attribute is parented directly off the dictionary root + * + * @param[in] da to check. + * @return + * - true if attribute is top level. + * - false if attribute is not top level. + */ +static inline bool fr_dict_attr_is_top_level(fr_dict_attr_t const *da) +{ + if (unlikely(!da) || unlikely(!da->parent)) return false; + if (!da->parent->flags.is_root) return false; + return true; +} + +/** Return the vendor number for an attribute + * + * @param[in] da The dictionary attribute to find the + * vendor for. + * @return + * - 0 this isn't a vendor specific attribute. + * - The vendor PEN. + */ +static inline uint32_t fr_dict_vendor_num_by_da(fr_dict_attr_t const *da) +{ + fr_dict_attr_t const *da_p = da; + + while (da_p->parent) { + if (da_p->type == FR_TYPE_VENDOR) break; + da_p = da_p->parent; + } + if (da_p->type != FR_TYPE_VENDOR) return 0; + + return da_p->attr; +} + fr_dict_t *fr_dict_by_da(fr_dict_attr_t const *da); int fr_dict_vendor_by_name(fr_dict_t const *dict, char const *name); fr_dict_vendor_t const *fr_dict_vendor_by_num(fr_dict_t const *dict, int vendor); +fr_dict_vendor_t const *fr_dict_vendor_by_da(fr_dict_attr_t const *da); + fr_dict_attr_t const *fr_dict_vendor_attr_by_da(fr_dict_attr_t const *da); fr_dict_attr_t const *fr_dict_vendor_attr_by_num(fr_dict_t const *dict, diff --git a/src/lib/ldap/control.c b/src/lib/ldap/control.c index dbc7f9ada67..21dd89dd0ba 100644 --- a/src/lib/ldap/control.c +++ b/src/lib/ldap/control.c @@ -189,7 +189,7 @@ int fr_ldap_control_add_session_tracking(fr_ldap_connection_t *conn, REQUEST *re for (vp = fr_pair_cursor_init(&cursor, &request->packet->vps); vp; vp = fr_pair_cursor_next(&cursor)) { - if (vp->da->vendor == 0) switch (vp->da->attr) { + if (fr_dict_attr_is_top_level(vp->da)) switch (vp->da->attr) { case FR_NAS_IP_ADDRESS: case FR_NAS_IPV6_ADDRESS: fr_pair_value_snprint(ipaddress, sizeof(ipaddress), vp, '\0'); diff --git a/src/lib/util/dict.c b/src/lib/util/dict.c index fbcb55e63de..512c83166d7 100644 --- a/src/lib/util/dict.c +++ b/src/lib/util/dict.c @@ -657,7 +657,7 @@ static inline int fr_dict_attr_child_add(fr_dict_attr_t *parent, fr_dict_attr_t } if (child_is_struct && !bin_is_struct) break; - else if (child->vendor <= (*bin)->vendor) break; /* Prioritise RFC attributes */ + else if (fr_dict_vendor_num_by_da(child) <= fr_dict_vendor_num_by_da(*bin)) break; /* Prioritise RFC attributes */ else if (child->attr <= (*bin)->attr) break; bin = &(*bin)->next; @@ -762,7 +762,6 @@ static int fr_dict_attr_set_name(fr_dict_attr_t **da, char const *name) * the dictionary root. * @param[in] name of the attribute. If NULL an OID string * will be created and set as the name. - * @param[in] vendor of the attribute. Deprecated. * @param[in] attr number. * @param[in] type of the attribute. * @param[in] flags to assign. @@ -772,7 +771,7 @@ static int fr_dict_attr_set_name(fr_dict_attr_t **da, char const *name) */ static fr_dict_attr_t *fr_dict_attr_alloc(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, - char const *name, unsigned int vendor, int attr, + char const *name, int attr, fr_type_t type, fr_dict_attr_flags_t const *flags) { fr_dict_attr_t *da; @@ -787,7 +786,6 @@ static fr_dict_attr_t *fr_dict_attr_alloc(TALLOC_CTX *ctx, talloc_set_type(da, fr_dict_attr_t); da->attr = attr; - da->vendor = vendor; da->type = type; memcpy(&da->flags, flags, sizeof(*flags)); da->parent = parent; @@ -838,7 +836,6 @@ static fr_dict_attr_t *fr_dict_attr_alloc(TALLOC_CTX *ctx, static fr_dict_attr_t *fr_dict_attr_add_by_name(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, int attr, fr_type_t type, fr_dict_attr_flags_t flags) { - unsigned int vendor; size_t namelen; fr_dict_attr_t *n; fr_dict_attr_t const *v; @@ -1405,16 +1402,7 @@ static fr_dict_attr_t *fr_dict_attr_add_by_name(fr_dict_t *dict, fr_dict_attr_t } } - /* - * Propogate vendor down the attribute tree. - */ - if (parent->type == FR_TYPE_VENDOR) { - vendor = parent->attr; - } else { - vendor = parent->vendor; - } - - n = fr_dict_attr_alloc(dict->pool, parent, name, vendor, attr, type, &flags); + n = fr_dict_attr_alloc(dict->pool, parent, name, attr, type, &flags); if (!n) { oom: fr_strerror_printf("Out of memory"); @@ -2586,7 +2574,7 @@ static int _dict_from_file(dict_from_file_ctx_t *ctx, memset(&flags, 0, sizeof(flags)); memcpy(&mutable, &ctx->parent, sizeof(mutable)); - new = fr_dict_attr_alloc(mutable, fr_dict_root(ctx->dict), "Vendor-Specific", 0, + new = fr_dict_attr_alloc(mutable, fr_dict_root(ctx->dict), "Vendor-Specific", FR_VENDOR_SPECIFIC, FR_TYPE_VSA, &flags); fr_dict_attr_child_add(mutable, new); vsa_da = new; @@ -2620,8 +2608,7 @@ static int _dict_from_file(dict_from_file_ctx_t *ctx, } memcpy(&mutable, &vsa_da, sizeof(mutable)); - new = fr_dict_attr_alloc(mutable, ctx->parent, - argv[1], 0, vendor, FR_TYPE_VENDOR, &flags); + new = fr_dict_attr_alloc(mutable, ctx->parent, argv[1], vendor, FR_TYPE_VENDOR, &flags); fr_dict_attr_child_add(mutable, new); vendor_da = new; @@ -2797,7 +2784,7 @@ int fr_dict_from_file(TALLOC_CTX *ctx, fr_dict_t **out, char const *dir, char co type_name = talloc_typed_asprintf(dict->pool, "Tmp-Cast-%s", p->name); n = fr_dict_attr_alloc(dict->pool, dict->root, type_name, - 0, FR_CAST_BASE + p->number, p->number, &flags); + FR_CAST_BASE + p->number, p->number, &flags); if (!n) goto error; if (!fr_hash_table_insert(dict->attributes_by_name, n)) goto error; @@ -2939,7 +2926,7 @@ fr_dict_attr_t *fr_dict_unknown_acopy(TALLOC_CTX *ctx, fr_dict_attr_t const *da) parent = da->parent; } - new = fr_dict_attr_alloc(ctx, parent, da->name, da->vendor, da->attr, da->type, &da->flags); + new = fr_dict_attr_alloc(ctx, parent, da->name, da->attr, da->type, &da->flags); new->parent = parent; new->depth = da->depth; @@ -3001,7 +2988,7 @@ fr_dict_attr_t const *fr_dict_unknown_add(fr_dict_t *dict, fr_dict_attr_t const if (fr_dict_vendor_add(dict, old->name, old->attr) < 0) return NULL; - n = fr_dict_attr_alloc(dict->pool, parent, old->name, old->vendor, old->attr, old->type, &flags); + n = fr_dict_attr_alloc(dict->pool, parent, old->name, old->attr, old->type, &flags); /* * Setup parenting for the attribute @@ -3065,7 +3052,7 @@ void fr_dict_unknown_free(fr_dict_attr_t const **da) /** Initialises an unknown attribute * - * Initialises a dict attr for an unknown attribute/vendor/type without adding + * Initialises a dict attr for an unknown attribute/type without adding * it to dictionary pools/hashes. * * Unknown attributes are used to transparently pass undecodeable attributes @@ -3078,8 +3065,7 @@ void fr_dict_unknown_free(fr_dict_attr_t const **da) * @param[in] vendor number. * @return 0 on success. */ -static int fr_dict_unknown_from_fields(fr_dict_attr_t *da, fr_dict_attr_t const *parent, - unsigned int vendor, unsigned int attr) +static int fr_dict_unknown_from_fields(fr_dict_attr_t *da, fr_dict_attr_t const *parent, unsigned int attr) { char *p; size_t len = 0; @@ -3093,7 +3079,6 @@ static int fr_dict_unknown_from_fields(fr_dict_attr_t *da, fr_dict_attr_t const memset(da, 0, FR_DICT_ATTR_SIZE); da->attr = attr; - da->vendor = vendor; da->type = FR_TYPE_OCTETS; da->flags.is_unknown = true; da->flags.is_raw = true; @@ -3183,7 +3168,7 @@ fr_dict_attr_t const *fr_dict_unknown_afrom_fields(TALLOC_CTX *ctx, fr_dict_attr return NULL; } - if (fr_dict_unknown_from_fields(n, parent, vendor, attr) < 0) { + if (fr_dict_unknown_from_fields(n, parent, attr) < 0) { talloc_free(p); parent = new_parent; /* Stupid const rules */ fr_dict_unknown_free(&parent); @@ -3257,7 +3242,7 @@ int fr_dict_unknown_vendor_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t **out, case FR_TYPE_EVS: if (!fr_cond_assert(!parent->flags.is_unknown)) return -1; - *out = fr_dict_attr_alloc(ctx, parent, NULL, 0, vendor, FR_TYPE_VENDOR, &flags); + *out = fr_dict_attr_alloc(ctx, parent, NULL, vendor, FR_TYPE_VENDOR, &flags); return 0; @@ -3309,7 +3294,7 @@ static int fr_dict_unknown_attr_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t **out, if (parent->type == FR_TYPE_VENDOR) vendor = parent->attr; - da = fr_dict_attr_alloc(ctx, parent, NULL, vendor, num, FR_TYPE_OCTETS, &flags); + da = fr_dict_attr_alloc(ctx, parent, NULL, num, FR_TYPE_OCTETS, &flags); if (!da) return -1; *out = da; @@ -3635,7 +3620,7 @@ void fr_dict_print(fr_dict_attr_t const *da, int depth) printf("%u%.*s%s \"%s\" vendor: %x (%u), num: %x (%u), type: %s, flags: %s\n", da->depth, depth, "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", name, da->name, - da->vendor, da->vendor, da->attr, da->attr, + fr_dict_vendor_num_by_da(da), fr_dict_vendor_num_by_da(da), da->attr, da->attr, fr_int2str(dict_attr_types, da->type, "?Unknown?"), buff); if (da->children) for (i = 0; i < talloc_array_length(da->children); i++) { @@ -3902,6 +3887,28 @@ fr_dict_vendor_t const *fr_dict_vendor_by_num(fr_dict_t const *dict, int vendorp return fr_hash_table_finddata(dict->vendors_by_num, &dv); } +/** Look up a vendor by its PEN + * + * @param[in] dict of protocol context we're operating in. + * If NULL the internal dictionary will be used. + * @param[in] vendorpec to search for. + * @return + * - The vendor. + * - NULL if no vendor with that number was regitered for this protocol. + */ +fr_dict_vendor_t const *fr_dict_vendor_by_da(fr_dict_attr_t const *da) +{ + fr_dict_t *dict; + fr_dict_vendor_t dv; + + dv.vendorpec = fr_dict_vendor_num_by_da(da); + if (!dv.vendorpec) return NULL; + + dict = fr_dict_by_da(da); + + return fr_hash_table_finddata(dict->vendors_by_num, &dv); +} + /** Return the vendor that parents this attribute * * @note Uses the dictionary hierachy to determine the parent @@ -4319,7 +4326,7 @@ void fr_dict_verify(char const *file, int line, fr_dict_attr_t const *da) if ((!da->flags.is_root) && (da->depth == 0)) { FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: " "Is not root, but depth is 0", - file, line, da->name, da->vendor, da->attr); + file, line, da->name, fr_dict_vendor_num_by_da(da), da->attr); if (!fr_cond_assert(0)) fr_exit_now(1); } @@ -4327,7 +4334,8 @@ void fr_dict_verify(char const *file, int line, fr_dict_attr_t const *da) if (da->depth > FR_DICT_MAX_TLV_STACK) { FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: " "Indicated depth (%u) greater than TLV stack depth (%u)", - file, line, da->name, da->vendor, da->attr, da->depth, FR_DICT_MAX_TLV_STACK); + file, line, da->name, fr_dict_vendor_num_by_da(da), da->attr, + da->depth, FR_DICT_MAX_TLV_STACK); if (!fr_cond_assert(0)) fr_exit_now(1); } @@ -4340,7 +4348,7 @@ void fr_dict_verify(char const *file, int line, fr_dict_attr_t const *da) if (i != (int)da_p->depth) { FR_FAULT_LOG("CONSISTENCY CHECK FAILED %s[%u]: fr_dict_attr_t %s vendor: %i, attr %i: " "Depth out of sequence, expected %i, got %u", - file, line, da->name, da->vendor, da->attr, i, da_p->depth); + file, line, da->name, fr_dict_vendor_num_by_da(da), da->attr, i, da_p->depth); if (!fr_cond_assert(0)) fr_exit_now(1); } diff --git a/src/lib/util/pair.c b/src/lib/util/pair.c index b59fdf264a0..d5a8b20ea78 100644 --- a/src/lib/util/pair.c +++ b/src/lib/util/pair.c @@ -187,7 +187,7 @@ VALUE_PAIR *fr_pair_afrom_child_num(TALLOC_CTX *ctx, fr_dict_attr_t const *paren * also fine... */ vendor = fr_dict_vendor_attr_by_da(parent); - if (vendor) vendor_id = vendor->vendor; + if (vendor) vendor_id = vendor->attr; da = fr_dict_unknown_afrom_fields(ctx, parent, vendor_id, attr); @@ -545,7 +545,7 @@ int fr_pair_to_unknown(VALUE_PAIR *vp) VP_VERIFY(vp); if (vp->da->flags.is_unknown) return 0; - da = fr_dict_unknown_afrom_fields(vp, vp->da->parent, vp->da->vendor, vp->da->attr); + da = fr_dict_unknown_afrom_fields(vp, vp->da->parent, fr_dict_vendor_num_by_da(vp->da), vp->da->attr); if (!da) return -1; fr_dict_unknown_free(&vp->da); /* Only frees unknown attributes */ @@ -832,9 +832,7 @@ void fr_pair_delete_by_num(VALUE_PAIR **head, unsigned int vendor, unsigned int for(i = *head; i; i = next) { VP_VERIFY(i); next = i->next; - if (i->da->parent->flags.is_root && - (i->da->attr == attr) && (i->da->vendor == 0) && - ATTR_TAG_MATCH(i, tag)) { + if (fr_dict_attr_is_top_level(i->da) && (i->da->attr == attr) && ATTR_TAG_MATCH(i, tag)) { *last = next; talloc_free(i); } else { @@ -846,7 +844,7 @@ void fr_pair_delete_by_num(VALUE_PAIR **head, unsigned int vendor, unsigned int VP_VERIFY(i); next = i->next; if ((i->da->parent->type == FR_TYPE_VENDOR) && - (i->da->attr == attr) && (i->da->vendor == vendor) && + (i->da->attr == attr) && (fr_dict_vendor_num_by_da(i->da) == vendor) && ATTR_TAG_MATCH(i, tag)) { *last = next; talloc_free(i); @@ -1597,7 +1595,7 @@ VALUE_PAIR *fr_pair_list_copy_by_num(TALLOC_CTX *ctx, VALUE_PAIR *from, /* * It's a VSA: copy it over. */ - if (vp->da->vendor != 0) goto do_copy; + if (!fr_dict_attr_is_top_level(vp->da)) goto do_copy; /* * It's Vendor-Specific: copy it over. @@ -1611,13 +1609,10 @@ VALUE_PAIR *fr_pair_list_copy_by_num(TALLOC_CTX *ctx, VALUE_PAIR *from, } if (!vendor) { - if (!vp->da->parent->flags.is_root || - (vp->da->attr != attr) || (vp->da->vendor != 0)) { - continue; - } + if (!fr_dict_attr_is_top_level(vp->da) || (vp->da->attr != attr)) continue; } else { if ((vp->da->parent->type != FR_TYPE_VENDOR) || - (vp->da->attr != attr) || (vp->da->vendor != vendor)) { + (vp->da->attr != attr) || (fr_dict_vendor_num_by_da(vp->da) != vendor)) { continue; } } @@ -1682,7 +1677,7 @@ void fr_pair_list_move(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from) /* * We never move Fall-Through. */ - if (!i->da->vendor && i->da->attr == FR_FALL_THROUGH && i->da->parent->flags.is_root) { + if (fr_dict_attr_is_top_level(i->da) && (i->da->attr == FR_FALL_THROUGH)) { tail_from = &(i->next); continue; } @@ -1756,7 +1751,8 @@ void fr_pair_list_move(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from) * Delete *all* of the attributes * of the same number. */ - fr_pair_delete_by_num(&found->next, found->da->vendor, found->da->attr, TAG_ANY); + fr_pair_delete_by_num(&found->next, + fr_dict_vendor_num_by_da(found->da), found->da->attr, TAG_ANY); /* * Remove this attribute from the @@ -1863,7 +1859,7 @@ static void fr_pair_list_move_by_num_internal(TALLOC_CTX *ctx, VALUE_PAIR **to, /* * It's a VSA: move it over. */ - if (i->da->vendor != 0) goto move; + if (!fr_dict_attr_is_top_level(i->da)) goto move; /* * It's Vendor-Specific: move it over. @@ -1881,14 +1877,13 @@ static void fr_pair_list_move_by_num_internal(TALLOC_CTX *ctx, VALUE_PAIR **to, * If it isn't an exact match, ignore it. */ if (!vendor) { - if (!(i->da->parent->flags.is_root && - (i->da->attr == attr) && (i->da->vendor == 0))) { + if (!(fr_dict_attr_is_top_level(i->da) && (i->da->attr == attr))) { iprev = i; continue; } } else { if (!((i->da->parent->type == FR_TYPE_VENDOR) && - (i->da->attr == attr) && (i->da->vendor == vendor))) { + (i->da->attr == attr) && (fr_dict_vendor_num_by_da(i->da) == vendor))) { iprev = i; continue; } diff --git a/src/lib/util/pair_cursor.c b/src/lib/util/pair_cursor.c index a13883d7e18..969bfe427b7 100644 --- a/src/lib/util/pair_cursor.c +++ b/src/lib/util/pair_cursor.c @@ -210,9 +210,7 @@ VALUE_PAIR *fr_pair_cursor_next_by_num(vp_cursor_t *cursor, unsigned int vendor, i != NULL; i = i->next) { VP_VERIFY(i); - if (i->da->parent->flags.is_root && - (i->da->attr == attr) && (i->da->vendor == 0) && - ATTR_TAG_MATCH(i, tag)) { + if (fr_dict_attr_is_top_level(i->da) && (i->da->attr == attr) && ATTR_TAG_MATCH(i, tag)) { break; } } @@ -222,7 +220,7 @@ VALUE_PAIR *fr_pair_cursor_next_by_num(vp_cursor_t *cursor, unsigned int vendor, i = i->next) { VP_VERIFY(i); if ((i->da->parent->type == FR_TYPE_VENDOR) && - (i->da->attr == attr) && (i->da->vendor == vendor) && + (i->da->attr == attr) && (fr_dict_vendor_num_by_da(i->da) == vendor) && ATTR_TAG_MATCH(i, tag)) { break; } diff --git a/src/lib/util/proto.c b/src/lib/util/proto.c index 8ae9f9cc469..cfdf7769ffc 100644 --- a/src/lib/util/proto.c +++ b/src/lib/util/proto.c @@ -84,7 +84,8 @@ void fr_proto_tlv_stack_print(char const *file, int line, char const *func, fr_d fprintf(fr_log_fp, "stk: %s%.*s: %s [%i] %s: %s, vendor: 0x%x (%u), attr: 0x%x (%u)\n", prefix, (int)(proto_log_indent - len), spaces, (i == (int)depth) ? ">" : " ", i, fr_int2str(dict_attr_types, tlv_stack[i]->type, "?Unknown?"), - tlv_stack[i]->name, tlv_stack[i]->vendor, tlv_stack[i]->vendor, + tlv_stack[i]->name, + fr_dict_vendor_num_by_da(tlv_stack[i]), fr_dict_vendor_num_by_da(tlv_stack[i]), tlv_stack[i]->attr, tlv_stack[i]->attr); } fprintf(fr_log_fp, "\n"); diff --git a/src/main/client.c b/src/main/client.c index e87f9a9be8b..8af5cbb5dc9 100644 --- a/src/main/client.c +++ b/src/main/client.c @@ -924,7 +924,7 @@ RADCLIENT *client_afrom_request(TALLOC_CTX *ctx, REQUEST *request) char const *value; char const *attr; - if (vp->da->vendor != 0) continue; + if (!fr_dict_attr_is_top_level(vp->da)) continue; if ((vp->da->attr < FR_FREERADIUS_CLIENT_IP_ADDRESS) || (vp->da->attr > FR_FREERADIUS_CLIENT_NAS_TYPE)) { diff --git a/src/main/cond_eval.c b/src/main/cond_eval.c index 4718a9f2cec..94761dc0a6a 100644 --- a/src/main/cond_eval.c +++ b/src/main/cond_eval.c @@ -1063,7 +1063,7 @@ void radius_pairmove(REQUEST *request, VALUE_PAIR **to, VALUE_PAIR *from, bool d fixup->password = NULL; for (vp = fixup->packet->vps; vp != NULL; vp = vp->next) { - if (vp->da->vendor) continue; + if (!fr_dict_attr_is_top_level(vp->da)) continue; if ((vp->da->attr == FR_USER_NAME) && !fixup->username) { fixup->username = vp; diff --git a/src/main/cond_tokenize.c b/src/main/cond_tokenize.c index 46c4c7c329a..436a47545ec 100644 --- a/src/main/cond_tokenize.c +++ b/src/main/cond_tokenize.c @@ -1099,24 +1099,27 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, CONF_ITEM *ci, char const *start, c->cast ? NULL : c->data.map->lhs->tmpl_da) < 0) { fr_dict_attr_t const *da = c->data.map->lhs->tmpl_da; - if ((da->vendor == 0) && - ((da->attr == FR_AUTH_TYPE) || - (da->attr == FR_AUTZ_TYPE) || - (da->attr == FR_ACCT_TYPE) || - (da->attr == FR_SESSION_TYPE) || - (da->attr == FR_POST_AUTH_TYPE) || - (da->attr == FR_PRE_PROXY_TYPE) || - (da->attr == FR_POST_PROXY_TYPE) || - (da->attr == FR_PRE_ACCT_TYPE) || - (da->attr == FR_RECV_COA_TYPE) || - (da->attr == FR_SEND_COA_TYPE))) { + if (!fr_dict_attr_is_top_level(da)) goto bad_type; + + switch (da->attr) { + case FR_AUTH_TYPE: + case FR_AUTZ_TYPE: + case FR_ACCT_TYPE: + case FR_SESSION_TYPE: + case FR_POST_AUTH_TYPE: + case FR_PRE_PROXY_TYPE: + case FR_POST_PROXY_TYPE: + case FR_PRE_ACCT_TYPE: + case FR_RECV_COA_TYPE: + case FR_SEND_COA_TYPE: /* * The types for these attributes are dynamically allocated * by module.c, so we can't enforce strictness here. */ c->pass2_fixup = PASS2_FIXUP_TYPE; - } else { + default: + bad_type: return_rhs("Failed to parse value for attribute"); } } diff --git a/src/main/map.c b/src/main/map.c index d0c8e0c306e..3822015180e 100644 --- a/src/main/map.c +++ b/src/main/map.c @@ -1963,8 +1963,7 @@ update: vp; vp = fr_cursor_next(&list)) { - if (!vp->da->parent->flags.is_root) continue; - if (vp->da->vendor != 0) continue; + if (!fr_dict_attr_is_top_level(vp->da)) continue; if (vp->da->flags.has_tag) continue; if (vp->vp_type != FR_TYPE_STRING) continue; @@ -2490,7 +2489,7 @@ int map_to_request(REQUEST *request, vp_map_t const *map, radius_map_getvalue_t * Wildcard: delete all of the matching ones, based on tag. */ if (map->lhs->tmpl_num == NUM_ANY) { - fr_pair_delete_by_num(list, map->lhs->tmpl_da->vendor, map->lhs->tmpl_da->attr, + fr_pair_delete_by_num(list, fr_dict_vendor_num_by_da(map->lhs->tmpl_da), map->lhs->tmpl_da->attr, map->lhs->tmpl_tag); dst = NULL; /* @@ -2689,9 +2688,7 @@ update: for (vp = fr_pair_cursor_init(&src_list, list); vp; vp = fr_pair_cursor_next(&src_list)) { - - if (!vp->da->parent->flags.is_root) continue; - if (vp->da->vendor != 0) continue; + if (!fr_dict_attr_is_top_level(vp->da)) continue; if (vp->da->flags.has_tag) continue; if (vp->vp_type != FR_TYPE_STRING) continue; diff --git a/src/main/pair.c b/src/main/pair.c index 4b48fad73bf..9f5f4316251 100644 --- a/src/main/pair.c +++ b/src/main/pair.c @@ -502,7 +502,7 @@ int paircompare(REQUEST *request, VALUE_PAIR *req_list, VALUE_PAIR *check, continue; } - if (!check_item->da->vendor) switch (check_item->da->attr) { + if (fr_dict_attr_is_top_level(check_item->da)) switch (check_item->da->attr) { /* * Attributes we skip during comparison. * These are "server" check items. diff --git a/src/main/radclient.c b/src/main/radclient.c index 2ae83ce919a..08cbd04e908 100644 --- a/src/main/radclient.c +++ b/src/main/radclient.c @@ -409,7 +409,7 @@ static int radclient_init(TALLOC_CTX *ctx, rc_file_pair_t *files) vp->vp_length = talloc_array_length(vp->vp_strvalue) - 1; } - if (vp->da->vendor == 0 ) switch (vp->da->attr) { + if (fr_dict_attr_is_top_level(vp->da)) switch (vp->da->attr) { case FR_RESPONSE_PACKET_TYPE: case FR_PACKET_TYPE: vp = fr_cursor_remove(&cursor); /* so we don't break the filter */ @@ -445,7 +445,7 @@ static int radclient_init(TALLOC_CTX *ctx, rc_file_pair_t *files) vp->vp_length = talloc_array_length(vp->vp_strvalue) - 1; } - if (!vp->da->vendor) switch (vp->da->attr) { + if (fr_dict_attr_is_top_level(vp->da)) switch (vp->da->attr) { default: break; diff --git a/src/main/unit_test_module.c b/src/main/unit_test_module.c index c19166a44a2..4754f4fdf45 100644 --- a/src/main/unit_test_module.c +++ b/src/main/unit_test_module.c @@ -176,7 +176,7 @@ static REQUEST *request_from_file(FILE *fp, fr_event_list_t *el, RADCLIENT *clie vp->type = VT_DATA; } - if (!vp->da->vendor) switch (vp->da->attr) { + if (fr_dict_attr_is_top_level(vp->da)) switch (vp->da->attr) { default: break; diff --git a/src/main/xlat_func.c b/src/main/xlat_func.c index 89f69776dab..73a220514fd 100644 --- a/src/main/xlat_func.c +++ b/src/main/xlat_func.c @@ -267,8 +267,9 @@ static ssize_t xlat_debug_attr(UNUSED TALLOC_CTX *ctx, UNUSED char **out, UNUSED for (vp = tmpl_cursor_init(NULL, &cursor, request, vpt); vp; vp = fr_cursor_next(&cursor)) { - FR_NAME_NUMBER const *type; - char *value; + fr_dict_vendor_t const *vendor; + FR_NAME_NUMBER const *type; + char *value; value = fr_pair_value_asprint(vp, vp, '\''); if (vp->da->flags.has_tag) { @@ -289,12 +290,8 @@ static ssize_t xlat_debug_attr(UNUSED TALLOC_CTX *ctx, UNUSED char **out, UNUSED if (!RDEBUG_ENABLED3) continue; - if (vp->da->vendor) { - fr_dict_vendor_t const *vendor; - - vendor = fr_dict_vendor_by_num(NULL, vp->da->vendor); - RIDEBUG2("Vendor : %i (%s)", vp->da->vendor, vendor ? vendor->name : "unknown"); - } + vendor = fr_dict_vendor_by_da(vp->da); + if (vendor) RIDEBUG2("Vendor : %i (%s)", vendor->vendorpec, vendor->name); RIDEBUG2("Type : %s", fr_int2str(dict_attr_types, vp->vp_type, "")); switch (vp->vp_type) { diff --git a/src/modules/proto_detail/proto_detail.c b/src/modules/proto_detail/proto_detail.c index 2c49e4f1bdf..968a143de22 100644 --- a/src/modules/proto_detail/proto_detail.c +++ b/src/modules/proto_detail/proto_detail.c @@ -305,8 +305,7 @@ static int mod_decode(void const *instance, REQUEST *request, uint8_t *const dat /* * Set the original src/dst ip/port */ - if (vp && (vp->da->vendor == 0) && (vp->da->attr >= FR_PACKET_SRC_IP_ADDRESS) && - (vp->da->attr <= FR_PACKET_DST_IPV6_ADDRESS)) switch (vp->da->attr) { + if (vp && fr_dict_attr_is_top_level(vp->da)) switch (vp->da->attr) { default: break; diff --git a/src/modules/proto_dhcpv4/dhcpclient.c b/src/modules/proto_dhcpv4/dhcpclient.c index 04f1f3b1075..b1b77fb53f7 100644 --- a/src/modules/proto_dhcpv4/dhcpclient.c +++ b/src/modules/proto_dhcpv4/dhcpclient.c @@ -149,9 +149,9 @@ static RADIUS_PACKET *request_init(char const *filename) /* * Allow to set packet type using DHCP-Message-Type */ - if (vp->da->vendor == DHCP_MAGIC_VENDOR && vp->da->attr == FR_DHCPV4_MESSAGE_TYPE) { + if ((fr_dict_vendor_num_by_da(vp->da) == DHCP_MAGIC_VENDOR) && vp->da->attr == FR_DHCPV4_MESSAGE_TYPE) { request->code = vp->vp_uint32 + FR_DHCPV4_OFFSET; - } else if (!vp->da->vendor) switch (vp->da->attr) { + } else if (fr_dict_attr_is_top_level(vp->da)) switch (vp->da->attr) { /* * Allow it to set the packet type in * the attributes read from the file. diff --git a/src/modules/rlm_attr_filter/rlm_attr_filter.c b/src/modules/rlm_attr_filter/rlm_attr_filter.c index f89630e51d1..68388b14cd1 100644 --- a/src/modules/rlm_attr_filter/rlm_attr_filter.c +++ b/src/modules/rlm_attr_filter/rlm_attr_filter.c @@ -110,8 +110,7 @@ static int attr_filter_getfile(TALLOC_CTX *ctx, char const *filename, PAIR_LIST * and we ignore Fall-Through, * then bitch about it, giving a good warning message. */ - if ((vp->da->vendor == 0) && - (vp->da->attr > 1000)) { + if (fr_dict_attr_is_top_level(vp->da) && (vp->da->attr > 1000)) { WARN("[%s]:%d Check item \"%s\"\n\tfound in filter list for realm \"%s\".\n", filename, entry->lineno, vp->da->name, entry->name); } @@ -199,16 +198,21 @@ static rlm_rcode_t CC_HINT(nonnull(1,2)) attr_filter_common(void const *instance for (check_item = fr_pair_cursor_init(&check, &pl->check); check_item; check_item = fr_pair_cursor_next(&check)) { - if (!check_item->da->vendor && - (check_item->da->attr == FR_FALL_THROUGH) && - (check_item->vp_uint32 == 1)) { - fall_through = 1; - continue; - } - else if (!check_item->da->vendor && check_item->da->attr == FR_RELAX_FILTER) { + if (fr_dict_attr_is_top_level(vp->da)) switch (check_item->da->attr) { + case FR_FALL_THROUGH: + if (check_item->vp_uint32 == 1) { + fall_through = 1; + continue; + } + break; + + case FR_RELAX_FILTER: relax_filter = check_item->vp_uint32; continue; - } + + default: + break; + } /* * If it is a SET operator, add the attribute to @@ -216,9 +220,8 @@ static rlm_rcode_t CC_HINT(nonnull(1,2)) attr_filter_common(void const *instance */ if (check_item->op == T_OP_SET ) { vp = fr_pair_copy(packet, check_item); - if (!vp) { - goto error; - } + if (!vp) goto error; + xlat_eval_do(request, vp); fr_pair_cursor_append(&out, vp); } @@ -247,7 +250,8 @@ static rlm_rcode_t CC_HINT(nonnull(1,2)) attr_filter_common(void const *instance * Vendor-Specific is special, and matches any VSA if the * comparison is always true. */ - if ((check_item->da->attr == FR_VENDOR_SPECIFIC) && (input_item->da->vendor != 0) && + if ((check_item->da->attr == FR_VENDOR_SPECIFIC) && + (fr_dict_vendor_num_by_da(input_item->da) != 0) && (check_item->op == T_OP_CMP_TRUE)) { pass++; continue; diff --git a/src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c b/src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c index 0ca008294c9..cd8680b97c1 100644 --- a/src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c +++ b/src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c @@ -207,7 +207,7 @@ static cache_status_t cache_entry_find(rlm_cache_entry_t **out, /* * Pull out the cache created date */ - if ((head->lhs->tmpl_da->vendor == 0) && (head->lhs->tmpl_da->attr == FR_CACHE_CREATED)) { + if (fr_dict_attr_is_top_level(head->lhs->tmpl_da) && (head->lhs->tmpl_da->attr == FR_CACHE_CREATED)) { vp_map_t *map; c->created = head->rhs->tmpl_value.vb_date; @@ -220,7 +220,7 @@ static cache_status_t cache_entry_find(rlm_cache_entry_t **out, /* * Pull out the cache expires date */ - if ((head->lhs->tmpl_da->vendor == 0) && (head->lhs->tmpl_da->attr == FR_CACHE_EXPIRES)) { + if (fr_dict_attr_is_top_level(head->lhs->tmpl_da) && (head->lhs->tmpl_da->attr == FR_CACHE_EXPIRES)) { vp_map_t *map; c->expires = head->rhs->tmpl_value.vb_date; diff --git a/src/modules/rlm_cache/rlm_cache.c b/src/modules/rlm_cache/rlm_cache.c index 90b382251e6..5f93db1cdd7 100644 --- a/src/modules/rlm_cache/rlm_cache.c +++ b/src/modules/rlm_cache/rlm_cache.c @@ -771,7 +771,9 @@ finish: vp; vp = fr_cursor_next(&cursor)) { again: - if (vp->da->vendor == 0) switch (vp->da->attr) { + if (!fr_dict_attr_is_top_level(vp->da)) continue; + + switch (vp->da->attr) { case FR_CACHE_TTL: case FR_CACHE_STATUS_ONLY: case FR_CACHE_ALLOW_MERGE: diff --git a/src/modules/rlm_cache/serialize.c b/src/modules/rlm_cache/serialize.c index 0715b69dddd..5c049bcd7a4 100644 --- a/src/modules/rlm_cache/serialize.c +++ b/src/modules/rlm_cache/serialize.c @@ -147,7 +147,7 @@ int cache_deserialize(rlm_cache_entry_t *c, char *in, ssize_t inlen) * Pull out the special attributes, and set the * relevant cache entry fields. */ - if (map->lhs->tmpl_da->vendor == 0) switch (map->lhs->tmpl_da->attr) { + if (fr_dict_attr_is_top_level(map->lhs->tmpl_da)) switch (map->lhs->tmpl_da->attr) { case FR_CACHE_CREATED: c->created = map->rhs->tmpl_value.vb_date; talloc_free(map); diff --git a/src/modules/rlm_detail/rlm_detail.c b/src/modules/rlm_detail/rlm_detail.c index 0c58c920064..f45d7c47f2f 100644 --- a/src/modules/rlm_detail/rlm_detail.c +++ b/src/modules/rlm_detail/rlm_detail.c @@ -307,7 +307,7 @@ static int detail_write(FILE *out, rlm_detail_t const *inst, REQUEST *request, R /* * Don't print passwords in old format... */ - if (compat && !vp->da->vendor && (vp->da->attr == FR_USER_PASSWORD)) continue; + if (compat && fr_dict_attr_is_top_level(vp->da) && (vp->da->attr == FR_USER_PASSWORD)) continue; /* * Print all of the attributes, operator should always be '='. diff --git a/src/modules/rlm_dict/rlm_dict.c b/src/modules/rlm_dict/rlm_dict.c index 3f182d6a72b..05aef66cff9 100644 --- a/src/modules/rlm_dict/rlm_dict.c +++ b/src/modules/rlm_dict/rlm_dict.c @@ -99,7 +99,7 @@ static ssize_t xlat_vendor(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen, if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0; - vendor = fr_dict_vendor_by_num(NULL, vp->da->vendor); + vendor = fr_dict_vendor_by_da(vp->da); if (!vendor) return 0; *out = talloc_typed_strdup(ctx, vendor->name); @@ -119,7 +119,7 @@ static ssize_t xlat_vendor_num(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) return 0; - *out = talloc_typed_asprintf(ctx, "%i", vp->da->vendor); + *out = talloc_typed_asprintf(ctx, "%i", fr_dict_vendor_num_by_da(vp->da)); return talloc_array_length(*out) - 1; } diff --git a/src/modules/rlm_eap/lib/base/eap_chbind.c b/src/modules/rlm_eap/lib/base/eap_chbind.c index 400bf8e9dea..07eba33efc1 100644 --- a/src/modules/rlm_eap/lib/base/eap_chbind.c +++ b/src/modules/rlm_eap/lib/base/eap_chbind.c @@ -42,7 +42,7 @@ static bool chbind_build_response(REQUEST *request, CHBIND_REQ *chbind) * Skip things which shouldn't be in channel bindings. */ if (vp->da->flags.encrypt != FLAG_ENCRYPT_NONE) continue; - if (!vp->da->vendor && (vp->da->attr == FR_MESSAGE_AUTHENTICATOR)) continue; + if (fr_dict_attr_is_top_level(vp->da) && (vp->da->attr == FR_MESSAGE_AUTHENTICATOR)) continue; total += 2 + vp->vp_length; } @@ -93,7 +93,7 @@ static bool chbind_build_response(REQUEST *request, CHBIND_REQ *chbind) fr_cursor_next(&cursor); continue; } - if (!vp->da->vendor && (vp->da->attr == FR_MESSAGE_AUTHENTICATOR)) goto next; + if (fr_dict_attr_is_top_level(vp->da) && (vp->da->attr == FR_MESSAGE_AUTHENTICATOR)) goto next; length = fr_radius_encode_pair(ptr, end - ptr, &cursor, NULL); ptr += length; diff --git a/src/modules/rlm_eap/lib/sim/decode.c b/src/modules/rlm_eap/lib/sim/decode.c index 40b7a6fa210..c13ceca3b3d 100644 --- a/src/modules/rlm_eap/lib/sim/decode.c +++ b/src/modules/rlm_eap/lib/sim/decode.c @@ -487,7 +487,8 @@ static ssize_t sim_decode_tlv(TALLOC_CTX *ctx, fr_cursor_t *cursor, /* * Build an unknown attr */ - unknown_child = fr_dict_unknown_afrom_fields(ctx, parent, parent->vendor, p[0]); + unknown_child = fr_dict_unknown_afrom_fields(ctx, parent, + fr_dict_vendor_num_by_da(parent), p[0]); if (!unknown_child) goto error; child = unknown_child; } @@ -696,7 +697,8 @@ static ssize_t sim_decode_pair_value(TALLOC_CTX *ctx, fr_cursor_t *cursor, fr_di * therefore of type "octets", and will be * handled below. */ - parent = fr_dict_unknown_afrom_fields(ctx, parent->parent, parent->vendor, parent->attr); + parent = fr_dict_unknown_afrom_fields(ctx, parent->parent, + fr_dict_vendor_num_by_da(parent), parent->attr); if (!parent) { fr_strerror_printf_push("%s[%d]: Internal sanity check failed", __FUNCTION__, __LINE__); return -1; diff --git a/src/modules/rlm_eap/lib/sim/encode.c b/src/modules/rlm_eap/lib/sim/encode.c index 36fcd9cc8a1..4d2a907bd9d 100644 --- a/src/modules/rlm_eap/lib/sim/encode.c +++ b/src/modules/rlm_eap/lib/sim/encode.c @@ -701,7 +701,7 @@ static ssize_t encode_rfc_hdr(uint8_t *out, size_t outlen, fr_dict_attr_t const return PAIR_ENCODE_ERROR; default: - if (((tlv_stack[depth]->vendor == 0) && (tlv_stack[depth]->attr == 0)) || + if (((fr_dict_vendor_num_by_da(tlv_stack[depth]) == 0) && (tlv_stack[depth]->attr == 0)) || (tlv_stack[depth]->attr > 255)) { fr_strerror_printf("%s: Called with non-standard attribute %u", __FUNCTION__, tlv_stack[depth]->attr); diff --git a/src/modules/rlm_eap/types/rlm_eap_fast/eap_fast.c b/src/modules/rlm_eap/types/rlm_eap_fast/eap_fast.c index 3065a7d5a57..40c17f0c010 100644 --- a/src/modules/rlm_eap/types/rlm_eap_fast/eap_fast.c +++ b/src/modules/rlm_eap/types/rlm_eap_fast/eap_fast.c @@ -505,7 +505,7 @@ static rlm_rcode_t CC_HINT(nonnull) process_reply(NDEBUG_UNUSED eap_session_t *e * the rest to be cleaned up. */ for (vp = fr_pair_cursor_init(&cursor, &reply->vps); vp; vp = fr_pair_cursor_next(&cursor)) { - if (vp->da->vendor != VENDORPEC_MICROSOFT) continue; + if (fr_dict_vendor_num_by_da(vp->da) != VENDORPEC_MICROSOFT) continue; /* FIXME must be a better way to capture/re-derive this later for ISK */ switch (vp->da->attr) { diff --git a/src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c b/src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c index 6b577780a87..4dd0a2ed3f2 100644 --- a/src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c +++ b/src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c @@ -253,8 +253,9 @@ do_value: * challenge) But if the client gets the challenge correct, * we're not too worried about the Id. */ - if (((vp->da->vendor == 0) && (vp->da->attr == FR_CHAP_CHALLENGE)) || - ((vp->da->vendor == VENDORPEC_MICROSOFT) && (vp->da->attr == FR_MSCHAP_CHALLENGE))) { + if ((fr_dict_attr_is_top_level(vp->da) && (vp->da->attr == FR_CHAP_CHALLENGE)) || + ((fr_dict_vendor_num_by_da(vp->da) == VENDORPEC_MICROSOFT) && (vp->da->attr == FR_MSCHAP_CHALLENGE)) + ) { uint8_t challenge[16]; uint8_t scratch[16]; @@ -329,7 +330,7 @@ static int vp2diameter(REQUEST *request, tls_session_t *tls_session, VALUE_PAIR */ length = vp->vp_length; - vendor = vp->da->vendor; + vendor = fr_dict_vendor_num_by_da(vp->da); if (vendor != 0) { attr = vp->da->attr & 0xffff; length |= ((uint32_t)1 << 31); @@ -486,7 +487,7 @@ static rlm_rcode_t CC_HINT(nonnull) process_reply(NDEBUG_UNUSED eap_session_t *e for (vp = fr_cursor_init(&cursor, &reply->vps); vp; vp = fr_cursor_next(&cursor)) { - switch (vp->da->vendor) { + switch (fr_dict_vendor_num_by_da(vp->da)) { case VENDORPEC_MICROSOFT: if (vp->da->attr == FR_MSCHAP2_SUCCESS) { RDEBUG("Got MS-CHAP2-Success, tunneling it to the client in a challenge"); @@ -536,7 +537,7 @@ static rlm_rcode_t CC_HINT(nonnull) process_reply(NDEBUG_UNUSED eap_session_t *e for (vp = fr_cursor_init(&cursor, &reply->vps); vp; vp = fr_cursor_next(&cursor)) { - switch (vp->da->vendor) { + switch (fr_dict_vendor_num_by_da(vp->da)) { case VENDORPEC_UKERNA: if (vp->da->attr == FR_UKERNA_CHBIND) { fr_cursor_prepend(&to_tunnel, fr_pair_copy(tls_session, vp)); diff --git a/src/modules/rlm_expr/paircmp.c b/src/modules/rlm_expr/paircmp.c index 47f8a63e1fd..c75fa18a802 100644 --- a/src/modules/rlm_expr/paircmp.c +++ b/src/modules/rlm_expr/paircmp.c @@ -81,7 +81,7 @@ static int presufcmp(UNUSED void *instance, RDEBUG3("Comparing name \"%s\" and check value \"%s\"", name, check->vp_strvalue); len = strlen(check->vp_strvalue); - if (check->da->vendor == 0) switch (check->da->attr) { + if (fr_dict_attr_is_top_level(check->da)) switch (check->da->attr) { case FR_PREFIX: ret = strncmp(name, check->vp_strvalue, len); if (ret == 0) diff --git a/src/modules/rlm_files/rlm_files.c b/src/modules/rlm_files/rlm_files.c index 533566b7bce..ef067a71fca 100644 --- a/src/modules/rlm_files/rlm_files.c +++ b/src/modules/rlm_files/rlm_files.c @@ -147,7 +147,7 @@ static int getusersfile(TALLOC_CTX *ctx, char const *filename, rbtree_t **ptree) * or it's a wire protocol, * ensure it has '=='. */ - if ((vp->da->vendor != 0) || + if ((fr_dict_vendor_num_by_da(vp->da) != 0) || (vp->da->attr < 0x100)) { WARN("[%s]:%d Changing '%s =' to '%s =='\n\tfor comparing RADIUS attribute in check item list for user %s", filename, entry->lineno, @@ -175,8 +175,7 @@ static int getusersfile(TALLOC_CTX *ctx, char const *filename, rbtree_t **ptree) * then bitch about it, giving a * good warning message. */ - if ((vp->da->vendor == 0) && - (vp->da->attr > 1000)) { + if (fr_dict_attr_is_top_level(vp->da) && (vp->da->attr > 1000)) { WARN("[%s]:%d Check item \"%s\"\n" "\tfound in reply item list for user \"%s\".\n" "\tThis attribute MUST go on the first line" diff --git a/src/modules/rlm_ldap/groups.c b/src/modules/rlm_ldap/groups.c index ac6a98e04d4..5a7d2944326 100644 --- a/src/modules/rlm_ldap/groups.c +++ b/src/modules/rlm_ldap/groups.c @@ -822,11 +822,13 @@ rlm_rcode_t rlm_ldap_check_cached(rlm_ldap_t const *inst, REQUEST *request, VALU * We return RLM_MODULE_INVALID here as an indication * the caller should try a dynamic group lookup instead. */ - vp = fr_pair_cursor_next_by_num(&cursor, inst->cache_da->vendor, inst->cache_da->attr, TAG_ANY); + vp = fr_pair_cursor_next_by_num(&cursor, fr_dict_vendor_num_by_da(inst->cache_da), + inst->cache_da->attr, TAG_ANY); if (!vp) return RLM_MODULE_INVALID; fr_pair_cursor_first(&cursor); - while ((vp = fr_pair_cursor_next_by_num(&cursor, inst->cache_da->vendor, inst->cache_da->attr, TAG_ANY))) { + while ((vp = fr_pair_cursor_next_by_num(&cursor, fr_dict_vendor_num_by_da(inst->cache_da), + inst->cache_da->attr, TAG_ANY))) { ret = fr_pair_cmp_op(T_OP_CMP_EQ, vp, check); if (ret == 1) { RDEBUG2("User found. Matched cached membership"); diff --git a/src/modules/rlm_mschap/rlm_mschap.c b/src/modules/rlm_mschap/rlm_mschap.c index a05d4eeef52..3bae76bf4b1 100644 --- a/src/modules/rlm_mschap/rlm_mschap.c +++ b/src/modules/rlm_mschap/rlm_mschap.c @@ -289,7 +289,7 @@ static ssize_t mschap_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, * For MS-CHAPv1, the NT-Response exists only * if the second octet says so. */ - if ((response->da->vendor == VENDORPEC_MICROSOFT) && + if ((fr_dict_vendor_num_by_da(response->da) == VENDORPEC_MICROSOFT) && (response->da->attr == FR_MSCHAP_RESPONSE) && ((response->vp_octets[1] & 0x01) == 0)) { REDEBUG("No NT-Response in MS-CHAP-Response"); @@ -1139,8 +1139,7 @@ static int CC_HINT(nonnull (1, 2, 4, 5 , 6)) do_mschap(rlm_mschap_t const *inst, * then calculate the hash of the NT hash. Doing this * here minimizes work for later. */ - if (!password->da->vendor && - (password->da->attr == FR_NT_PASSWORD)) { + if (fr_dict_attr_is_top_level(password->da) && (password->da->attr == FR_NT_PASSWORD)) { fr_md4_calc(nthashhash, password->vp_octets, MD4_DIGEST_LENGTH); } @@ -1672,11 +1671,9 @@ static rlm_rcode_t CC_HINT(nonnull) process_cpw_request(rlm_mschap_t const *inst for (nt_enc = fr_cursor_init(&cursor, &request->packet->vps); nt_enc; nt_enc = fr_cursor_next(&cursor)) { - if (nt_enc->da->vendor != VENDORPEC_MICROSOFT) - continue; + if (fr_dict_vendor_num_by_da(nt_enc->da) != VENDORPEC_MICROSOFT) continue; - if (nt_enc->da->attr != FR_MSCHAP_NT_ENC_PW) - continue; + if (nt_enc->da->attr != FR_MSCHAP_NT_ENC_PW) continue; if (nt_enc->vp_length < 4) { REDEBUG("MS-CHAP-NT-Enc-PW with invalid format"); diff --git a/src/modules/rlm_pap/rlm_pap.c b/src/modules/rlm_pap/rlm_pap.c index 9306236e987..8b90eb25631 100644 --- a/src/modules/rlm_pap/rlm_pap.c +++ b/src/modules/rlm_pap/rlm_pap.c @@ -1354,8 +1354,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, UNUSED void fr_cursor_t cursor; rlm_rcode_t (*auth_func)(rlm_pap_t const *, REQUEST *, VALUE_PAIR *) = NULL; - if (!request->password || - (request->password->da->vendor != 0) || + if (!request->password || !fr_dict_attr_is_top_level(request->password->da) || (request->password->da->attr != FR_USER_PASSWORD)) { REDEBUG("You set 'Auth-Type = PAP' for a request that does not contain a User-Password attribute!"); return RLM_MODULE_INVALID; @@ -1384,7 +1383,9 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, UNUSED void for (vp = fr_cursor_init(&cursor, &request->control); vp; vp = fr_cursor_next(&cursor)) { - if (!vp->da->vendor) switch (vp->da->attr) { + if (!fr_dict_attr_is_top_level(vp->da)) continue; + + switch (vp->da->attr) { case FR_CLEARTEXT_PASSWORD: auth_func = &pap_auth_clear; break; diff --git a/src/modules/rlm_passwd/rlm_passwd.c b/src/modules/rlm_passwd/rlm_passwd.c index 7dc70c13d84..e7eec20878b 100644 --- a/src/modules/rlm_passwd/rlm_passwd.c +++ b/src/modules/rlm_passwd/rlm_passwd.c @@ -537,7 +537,8 @@ static rlm_rcode_t CC_HINT(nonnull) mod_passwd_map(void *instance, UNUSED void * for (i = fr_pair_cursor_init(&cursor, &key); i; - i = fr_pair_cursor_next_by_num(&cursor, inst->keyattr->vendor, inst->keyattr->attr, TAG_ANY)) { + i = fr_pair_cursor_next_by_num(&cursor, fr_dict_vendor_num_by_da(inst->keyattr), + inst->keyattr->attr, TAG_ANY)) { /* * Ensure we have the string form of the attribute */ diff --git a/src/modules/rlm_radutmp/rlm_radutmp.c b/src/modules/rlm_radutmp/rlm_radutmp.c index f13b2b85b92..8d972bb5832 100644 --- a/src/modules/rlm_radutmp/rlm_radutmp.c +++ b/src/modules/rlm_radutmp/rlm_radutmp.c @@ -220,7 +220,9 @@ static rlm_rcode_t CC_HINT(nonnull) mod_accounting(void *instance, UNUSED void * for (vp = fr_cursor_init(&cursor, &request->packet->vps); vp; vp = fr_cursor_next(&cursor)) { - if (!vp->da->vendor) switch (vp->da->attr) { + if (!fr_dict_attr_is_top_level(vp->da)) continue; + + switch (vp->da->attr) { case FR_LOGIN_IP_HOST: case FR_FRAMED_IP_ADDRESS: ut.framed_address = vp->vp_ipv4addr; diff --git a/src/modules/rlm_sql/rlm_sql.c b/src/modules/rlm_sql/rlm_sql.c index 55cb41049eb..8378b2bfa37 100644 --- a/src/modules/rlm_sql/rlm_sql.c +++ b/src/modules/rlm_sql/rlm_sql.c @@ -638,7 +638,7 @@ int sql_set_user(rlm_sql_t const *inst, REQUEST *request, char const *username) /* * Delete any existing SQL-User-Name, and replace it with ours. */ - fr_pair_delete_by_num(&request->packet->vps, vp->da->vendor, vp->da->attr, TAG_ANY); + fr_pair_delete_by_num(&request->packet->vps, fr_dict_vendor_num_by_da(vp->da), vp->da->attr, TAG_ANY); fr_pair_add(&request->packet->vps, vp); return 0; @@ -647,7 +647,7 @@ int sql_set_user(rlm_sql_t const *inst, REQUEST *request, char const *username) /* * Do a set/unset user, so it's a bit clearer what's going on. */ -#define sql_unset_user(_i, _r) fr_pair_delete_by_num(&_r->packet->vps, _i->sql_user->vendor, _i->sql_user->attr, TAG_ANY) +#define sql_unset_user(_i, _r) fr_pair_delete_by_num(&_r->packet->vps, fr_dict_vendor_num_by_da(_i->sql_user), _i->sql_user->attr, TAG_ANY) static int sql_get_grouplist(rlm_sql_t const *inst, rlm_sql_handle_t **handle, REQUEST *request, rlm_sql_grouplist_t **phead) diff --git a/src/modules/rlm_sqlcounter/rlm_sqlcounter.c b/src/modules/rlm_sqlcounter/rlm_sqlcounter.c index 1fee1017380..46473351015 100644 --- a/src/modules/rlm_sqlcounter/rlm_sqlcounter.c +++ b/src/modules/rlm_sqlcounter/rlm_sqlcounter.c @@ -409,7 +409,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, UNUSED void *t * The REAL username, after stripping. */ if ((inst->key_attr->tmpl_list == PAIR_LIST_REQUEST) && - (inst->key_attr->tmpl_da->vendor == 0) && (inst->key_attr->tmpl_da->attr == FR_USER_NAME)) { + fr_dict_attr_is_top_level(inst->key_attr->tmpl_da) && (inst->key_attr->tmpl_da->attr == FR_USER_NAME)) { key_vp = request->username; } else { tmpl_find_vp(&key_vp, request, inst->key_attr); @@ -482,7 +482,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, UNUSED void *t * limit, so that the user will not need to login * again. Do this only for Session-Timeout. */ - if (((inst->reply_attr->tmpl_da->vendor == 0) && + if ((fr_dict_attr_is_top_level(inst->reply_attr->tmpl_da) && (inst->reply_attr->tmpl_da->attr == FR_SESSION_TIMEOUT)) && inst->reset_time && (res >= (uint64_t)(inst->reset_time - request->packet->timestamp.tv_sec))) { uint64_t to_reset = inst->reset_time - request->packet->timestamp.tv_sec; diff --git a/src/modules/rlm_unix/rlm_unix.c b/src/modules/rlm_unix/rlm_unix.c index 91a0240a75b..f59168e68db 100644 --- a/src/modules/rlm_unix/rlm_unix.c +++ b/src/modules/rlm_unix/rlm_unix.c @@ -422,7 +422,9 @@ static rlm_rcode_t CC_HINT(nonnull) mod_accounting(void *instance, UNUSED void * for (vp = fr_cursor_init(&cursor, &request->packet->vps); vp; vp = fr_cursor_next(&cursor)) { - if (!vp->da->vendor) switch (vp->da->attr) { + if (!fr_dict_attr_is_top_level(vp->da)) continue; + + switch (vp->da->attr) { case FR_USER_NAME: if (vp->vp_length >= sizeof(ut.ut_name)) { memcpy(ut.ut_name, vp->vp_strvalue, sizeof(ut.ut_name)); diff --git a/src/modules/rlm_winbind/rlm_winbind.c b/src/modules/rlm_winbind/rlm_winbind.c index d1cb8c450ac..eaba50ce331 100644 --- a/src/modules/rlm_winbind/rlm_winbind.c +++ b/src/modules/rlm_winbind/rlm_winbind.c @@ -469,8 +469,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, UNUSED void /* * Check the admin hasn't been silly */ - if (!request->password || - (request->password->da->vendor != 0) || + if (!request->password || !fr_dict_attr_is_top_level(request->password->da) || (request->password->da->attr != FR_USER_PASSWORD)) { REDEBUG("You set 'Auth-Type = winbind' for a request that does not contain a User-Password attribute!"); return RLM_MODULE_INVALID; diff --git a/src/protocols/dhcpv4/decode.c b/src/protocols/dhcpv4/decode.c index 837835149ab..51160339d17 100644 --- a/src/protocols/dhcpv4/decode.c +++ b/src/protocols/dhcpv4/decode.c @@ -279,7 +279,8 @@ static ssize_t decode_tlv(TALLOC_CTX *ctx, fr_cursor_t *cursor, fr_dict_attr_t c /* * Build an unknown attr */ - unknown_child = fr_dict_unknown_afrom_fields(ctx, parent, parent->vendor, p[0]); + unknown_child = fr_dict_unknown_afrom_fields(ctx, parent, + fr_dict_vendor_num_by_da(parent), p[0]); if (!unknown_child) return -1; child = unknown_child; } diff --git a/src/protocols/dhcpv4/encode.c b/src/protocols/dhcpv4/encode.c index 570eb98e894..98166ae214c 100644 --- a/src/protocols/dhcpv4/encode.c +++ b/src/protocols/dhcpv4/encode.c @@ -289,7 +289,7 @@ ssize_t fr_dhcpv4_encode_option(uint8_t *out, size_t outlen, fr_cursor_t *cursor vp = fr_cursor_current(cursor); if (!vp) return -1; - if (vp->da->vendor != DHCP_MAGIC_VENDOR) goto next; /* not a DHCP option */ + if (fr_dict_vendor_num_by_da(vp->da) != DHCP_MAGIC_VENDOR) goto next; /* not a DHCP option */ if (vp->da->attr == FR_DHCPV4_MESSAGE_TYPE) goto next; /* already done */ if ((vp->da->attr > 255) && (DHCP_BASE_ATTR(vp->da->attr) != FR_DHCPV4_OPTION_82)) { next: diff --git a/src/protocols/dhcpv6/encode.c b/src/protocols/dhcpv6/encode.c index a9ecdd02043..7d87e937664 100644 --- a/src/protocols/dhcpv6/encode.c +++ b/src/protocols/dhcpv6/encode.c @@ -585,21 +585,6 @@ static ssize_t encode_rfc_hdr(uint8_t *out, size_t outlen, FR_PROTO_STACK_PRINT(tlv_stack, depth); - switch (da->type) { - case FR_TYPE_STRUCTURAL: - fr_strerror_printf("%s: Called with structural type %s", __FUNCTION__, - fr_int2str(dict_attr_types, da->type, "?Unknown?")); - return PAIR_ENCODE_ERROR; - - default: - if (((da->vendor == 0) && (da->attr == 0)) || (da->attr > UINT16_MAX)) { - fr_strerror_printf("%s: Called with non-standard attribute %u", __FUNCTION__, - tlv_stack[depth]->attr); - return PAIR_ENCODE_ERROR; - } - break; - } - CHECK_FREESPACE(outlen, OPT_HDR_LEN); /* diff --git a/src/protocols/radius/base.c b/src/protocols/radius/base.c index cbd564484fb..3b6202c5601 100644 --- a/src/protocols/radius/base.c +++ b/src/protocols/radius/base.c @@ -924,11 +924,8 @@ ssize_t fr_radius_encode(uint8_t *packet, size_t packet_len, uint8_t const *orig /* * Ignore non-wire attributes, but allow extended * attributes. - * - * @fixme We should be able to get rid of this check - * and just look at da->flags.internal */ - if (vp->da->flags.internal || ((vp->da->vendor == 0) && (vp->da->attr >= 256))) { + if (vp->da->flags.internal) { #ifndef NDEBUG /* * Permit the admin to send BADLY formatted @@ -954,7 +951,7 @@ ssize_t fr_radius_encode(uint8_t *packet, size_t packet_len, uint8_t const *orig * Set the Message-Authenticator to the correct * length and initial value. */ - if (!vp->da->vendor && (vp->da->attr == FR_MESSAGE_AUTHENTICATOR)) { + if (fr_dict_attr_is_top_level(vp->da) && (vp->da->attr == FR_MESSAGE_AUTHENTICATOR)) { last_len = 16; } else { last_len = vp->vp_length; diff --git a/src/protocols/radius/decode.c b/src/protocols/radius/decode.c index c718316ea29..3a78cbb91c3 100644 --- a/src/protocols/radius/decode.c +++ b/src/protocols/radius/decode.c @@ -426,7 +426,8 @@ ssize_t fr_radius_decode_tlv(TALLOC_CTX *ctx, fr_cursor_t *cursor, /* * Build an unknown attr */ - unknown_child = fr_dict_unknown_afrom_fields(ctx, parent, parent->vendor, p[0]); + unknown_child = fr_dict_unknown_afrom_fields(ctx, parent, + fr_dict_vendor_num_by_da(parent), p[0]); if (!unknown_child) { error: fr_pair_list_free(&head); @@ -499,13 +500,15 @@ static ssize_t fr_radius_decode_struct(TALLOC_CTX *ctx, fr_cursor_t *cursor, /* * Build an unknown attr of the entire STRUCT. */ - child = fr_dict_unknown_afrom_fields(ctx, parent->parent, parent->vendor, parent->attr); + child = fr_dict_unknown_afrom_fields(ctx, parent->parent, + fr_dict_vendor_num_by_da(parent), parent->attr); if (!child) return -1; /* * Decode the whole STRUCT as an unknown attribute */ - child_len = fr_radius_decode_pair_value(ctx, &child_cursor, child, data, data_len, data_len, decoder_ctx); + child_len = fr_radius_decode_pair_value(ctx, &child_cursor, child, + data, data_len, data_len, decoder_ctx); if (child_len < 0) return child_len; break; } @@ -1223,7 +1226,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_cursor_t *cursor, fr_dic child = fr_dict_attr_child_by_num(parent, p[0]); if (!child) { if ((p[0] != FR_VENDOR_SPECIFIC) || (data_len < (3 + 4 + 1))) { - /* da->attr < 255, da->vendor == 0 */ + /* da->attr < 255, fr_dict_vendor_num_by_da(da) == 0 */ child = fr_dict_unknown_afrom_fields(ctx, parent, 0, p[0]); } else { /* @@ -1352,7 +1355,8 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_cursor_t *cursor, fr_dic * therefore of type "octets", and will be * handled below. */ - parent = fr_dict_unknown_afrom_fields(ctx, parent->parent, parent->vendor, parent->attr); + parent = fr_dict_unknown_afrom_fields(ctx, parent->parent, + fr_dict_vendor_num_by_da(parent), parent->attr); if (!parent) { fr_strerror_printf("%s: Internal sanity check %d", __FUNCTION__, __LINE__); return -1; diff --git a/src/protocols/radius/encode.c b/src/protocols/radius/encode.c index e3e198dd792..256d3669714 100644 --- a/src/protocols/radius/encode.c +++ b/src/protocols/radius/encode.c @@ -1098,7 +1098,7 @@ static ssize_t encode_rfc_hdr_internal(uint8_t *out, size_t outlen, return -1; default: - if (((tlv_stack[depth]->vendor == 0) && (tlv_stack[depth]->attr == 0)) || + if (((fr_dict_vendor_num_by_da(tlv_stack[depth]) == 0) && (tlv_stack[depth]->attr == 0)) || (tlv_stack[depth]->attr > 255)) { fr_strerror_printf("%s: Called with non-standard attribute %u", __FUNCTION__, tlv_stack[depth]->attr); @@ -1305,7 +1305,7 @@ static int encode_wimax_hdr(uint8_t *out, size_t outlen, out = start; out[0] = FR_VENDOR_SPECIFIC; out[1] = 9; - lvalue = htonl(vp->da->vendor); + lvalue = htonl(fr_dict_vendor_num_by_da(vp->da)); memcpy(out + 2, &lvalue, 4); /* @@ -1374,10 +1374,10 @@ static int encode_vsa_hdr(uint8_t *out, size_t outlen, } /* - * Double-check for WiMAX format. + * Double-check for WiMAX format */ - if (da->vendor == VENDORPEC_WIMAX) { - return encode_wimax_hdr(out, outlen, tlv_stack, depth + 1, cursor, encoder_ctx); + if (fr_dict_vendor_num_by_da(tlv_stack[depth + 1]) == VENDORPEC_WIMAX) { + return encode_wimax_hdr(out, outlen, tlv_stack, depth, cursor, encoder_ctx); } /* @@ -1450,7 +1450,7 @@ static int encode_rfc_hdr(uint8_t *out, size_t outlen, fr_dict_attr_t const **tl * Attribute 0 is fine as a TLV leaf, or VSA, but not * in the original standards space. */ - if (((tlv_stack[depth]->vendor == 0) && (tlv_stack[depth]->attr == 0)) || + if (((fr_dict_vendor_num_by_da(tlv_stack[depth]) == 0) && (tlv_stack[depth]->attr == 0)) || (tlv_stack[depth]->attr > 255)) { fr_strerror_printf("%s: Called with non-standard attribute %u", __FUNCTION__, vp->da->attr); return -1; @@ -1474,7 +1474,7 @@ static int encode_rfc_hdr(uint8_t *out, size_t outlen, fr_dict_attr_t const **tl /* * Message-Authenticator is hard-coded. */ - if (!vp->da->vendor && (vp->da->attr == FR_MESSAGE_AUTHENTICATOR)) { + if (fr_dict_attr_is_top_level(vp->da) && (vp->da->attr == FR_MESSAGE_AUTHENTICATOR)) { if (outlen < 18) return -1; out[0] = FR_MESSAGE_AUTHENTICATOR; @@ -1536,7 +1536,7 @@ ssize_t fr_radius_encode_pair(uint8_t *out, size_t outlen, fr_cursor_t *cursor, * attributes. */ if (fr_radius_attr_len(vp) == 0) { - if ((vp->da->vendor != 0) || + if (!fr_dict_attr_is_top_level(vp->da) || ((vp->da->attr != FR_CHARGEABLE_USER_IDENTITY) && (vp->da->attr != FR_MESSAGE_AUTHENTICATOR))) { next_encodable(cursor); @@ -1584,7 +1584,7 @@ ssize_t fr_radius_encode_pair(uint8_t *out, size_t outlen, fr_cursor_t *cursor, break; case FR_TYPE_VSA: - if (vp->da->vendor == VENDORPEC_WIMAX) { + if (fr_dict_vendor_num_by_da(da) == VENDORPEC_WIMAX) { /* * WiMAX has a non-standard format for * its VSAs. And, it can do "long"