From: Alan T. DeKok Date: Fri, 26 Jan 2024 03:04:20 +0000 (-0500) Subject: encode foreign references X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ca34947333ebde111da5248810d0634741673059;p=thirdparty%2Ffreeradius-server.git encode foreign references --- diff --git a/src/protocols/radius/base.c b/src/protocols/radius/base.c index 52c20a93018..7238489e215 100644 --- a/src/protocols/radius/base.c +++ b/src/protocols/radius/base.c @@ -1255,14 +1255,6 @@ static bool attr_valid(UNUSED fr_dict_t *dict, fr_dict_attr_t const *parent, return true; } - /* - * The RADIUS encoder does not handle groups. - */ - if ((type == FR_TYPE_GROUP) && !flags->internal) { - fr_strerror_const("The RADIUS protocol cannot encode attributes of type 'group'"); - return false; - } - if (flag_extended(flags)) { if (type != FR_TYPE_TLV) { fr_strerror_const("The 'long' or 'extended' flag can only be used for attributes of type 'tlv'"); diff --git a/src/protocols/radius/encode.c b/src/protocols/radius/encode.c index c1f1ffeafa5..fd489fd50aa 100644 --- a/src/protocols/radius/encode.c +++ b/src/protocols/radius/encode.c @@ -801,6 +801,35 @@ static ssize_t encode_extended(fr_dbuff_t *dbuff, } else if (da->type == FR_TYPE_STRUCT) { slen = fr_struct_to_network(&work_dbuff, da_stack, my_depth, cursor, encode_ctx, encode_value, encode_child); + } else if (da->type == FR_TYPE_GROUP) { + fr_dict_attr_t const *ref; + fr_dict_protocol_t const *proto; + + ref = fr_dict_attr_ref(da); + if (!ref) { + fr_strerror_printf("Invalid attribute reference for %s", da->name); + return PAIR_ENCODE_SKIPPED; + } + + fr_assert(ref->dict != dict_radius); + + proto = fr_dict_protocol(ref->dict); + fr_assert(proto != NULL); + + if (!proto->encode) { + fr_strerror_printf("Attribute %s -> %s does not have an encoder", da->name, ref->name); + return PAIR_ENCODE_SKIPPED; + } + + /* + * The foreign functions don't take a cursor, so we have to update the cursor ourselves. + */ + slen = proto->encode(&work_dbuff, &vp->vp_group); + if (slen > 0) { + vp = fr_dcursor_next(cursor); + fr_proto_da_stack_build(da_stack, vp ? vp->da : NULL); + } + } else { fr_assert(da->type == FR_TYPE_TLV);