From: Alan T. DeKok Date: Fri, 17 Feb 2023 21:28:32 +0000 (-0500) Subject: allow for "format=string" for PROTOCOLs X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c0f45909c83775285c68ae0b7e176587552da003;p=thirdparty%2Ffreeradius-server.git allow for "format=string" for PROTOCOLs in which case most attributes need to be created using DEFINE, and not using ATTRIBUTE. But VENDOR and MEMBER of STRUCT can still use number --- diff --git a/src/lib/util/dict_priv.h b/src/lib/util/dict_priv.h index 7a6a9edc598..8fcca8efa58 100644 --- a/src/lib/util/dict_priv.h +++ b/src/lib/util/dict_priv.h @@ -81,6 +81,8 @@ struct fr_dict { bool autoloaded; //!< manual vs autoload + bool string_based; //!< TACACS, etc. + fr_hash_table_t *vendors_by_name; //!< Lookup vendor by name. fr_hash_table_t *vendors_by_num; //!< Lookup vendor by PEN. diff --git a/src/lib/util/dict_tokenize.c b/src/lib/util/dict_tokenize.c index 0f4ae6c404c..46e038a7f9c 100644 --- a/src/lib/util/dict_tokenize.c +++ b/src/lib/util/dict_tokenize.c @@ -1738,6 +1738,7 @@ static int dict_read_process_protocol(char **argv, int argc) fr_dict_t *dict; fr_dict_attr_t *mutable; bool require_dl = false; + bool string_based = false; if ((argc < 2) || (argc > 3)) { fr_strerror_const("Missing arguments after PROTOCOL. Expected PROTOCOL "); @@ -1778,6 +1779,12 @@ static int dict_read_process_protocol(char **argv, int argc) goto post_option; } + if (strcmp(argv[2], "format=string") == 0) { + type_size = 4; + string_based = true; + goto post_option; + } + if (strncasecmp(argv[2], "format=", 7) != 0) { fr_strerror_printf("Invalid format for PROTOCOL. Expected 'format=', got '%s'", argv[2]); return -1; @@ -1852,6 +1859,7 @@ post_option: if (dict_protocol_add(dict) < 0) goto error; mutable = UNCONST(fr_dict_attr_t *, dict->root); + dict->string_based = string_based; if (!type_size) { mutable->flags.type_size = dict->default_type_size; mutable->flags.length = dict->default_type_length; @@ -2534,12 +2542,7 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, vsa_da = da; - } else if (!ctx->dict->vsa_parent) { - fr_strerror_printf_push("BEGIN-VENDOR is forbidden for protocol %s - it has no ATTRIBUTE of type 'vsa'", - ctx->dict->root->name); - goto error; - - } else { + } else if (ctx->dict->vsa_parent) { /* * Check that the protocol-specific VSA parent exists. */ @@ -2549,6 +2552,15 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, vendor->name); goto error; } + + } else if (ctx->dict->string_based) { + vsa_da = ctx->dict->root; + + } else { + fr_strerror_printf_push("BEGIN-VENDOR is forbidden for protocol %s - it has no ATTRIBUTE of type 'vsa'", + ctx->dict->root->name); + goto error; + } /* @@ -2596,6 +2608,8 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, } vendor_da = new; + } else { + fr_assert(vendor_da->type == FR_TYPE_VENDOR); } if (dict_gctx_push(ctx, vendor_da) < 0) goto error; diff --git a/src/lib/util/dict_util.c b/src/lib/util/dict_util.c index 4ef9e8ca5c5..bfc35edf6e3 100644 --- a/src/lib/util/dict_util.c +++ b/src/lib/util/dict_util.c @@ -1078,9 +1078,9 @@ int dict_attr_child_add(fr_dict_attr_t *parent, fr_dict_attr_t *child) /* * The parent has children by name only, not by number. Don't even bother trying to track - * numbers. + * numbers, except for VENDOR in root, and MEMBER of a struct. */ - if (parent->flags.name_only && (parent->type != FR_TYPE_STRUCT)) return 0; + if (!parent->flags.is_root && parent->flags.name_only && (parent->type != FR_TYPE_STRUCT)) return 0; /* * We only allocate the pointer array *if* the parent has children.