]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allow for "format=string" for PROTOCOLs
authorAlan T. DeKok <aland@freeradius.org>
Fri, 17 Feb 2023 21:28:32 +0000 (16:28 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 17 Feb 2023 21:28:32 +0000 (16:28 -0500)
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

src/lib/util/dict_priv.h
src/lib/util/dict_tokenize.c
src/lib/util/dict_util.c

index 7a6a9edc59898b2e71d8ca8ced654adb09857970..8fcca8efa5829044153a79bc14168d841ac18007 100644 (file)
@@ -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.
 
index 0f4ae6c404cce081ca9ebb82b71386c21d44cb10..46e038a7f9cd7d6222008d1c1c1f66701a1fdf17 100644 (file)
@@ -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 <num> <name>");
@@ -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;
index 4ef9e8ca5c5ede285bdd590b75f4d0181b7e1b0f..bfc35edf6e350bdd9681478116ee278b362a6519 100644 (file)
@@ -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.