]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add ALIAS support
authorAlan T. DeKok <aland@freeradius.org>
Fri, 9 Oct 2020 18:48:54 +0000 (14:48 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 9 Oct 2020 20:01:55 +0000 (16:01 -0400)
which is a simpler way of defining multiple names for one
attribute.  This keyword allows aliasing of the name, without
the need to repeat number, data type, etc.

At some point we will forbid duplicate ATTRIBUTE definitions,
and instead require the use of ALIAS

man/man5/dictionary.5
scripts/dict/format.pl
src/lib/util/dict_tokenize.c

index 90ae5e2a0c19d784ea5e590c60667da0ad113488..7c129d9d0fff2dc6aff41ab61e4a2cd7e177dc72 100644 (file)
@@ -10,7 +10,7 @@
 .RE
 .sp
 ..
-.TH dictionary 5 "14 May 2019"
+.TH dictionary 5 "09 Oct 2020"
 .SH NAME
 dictionary \- RADIUS dictionary file
 .SH DESCRIPTION
@@ -43,9 +43,24 @@ Every line starting with a hash sign
 is treated as comment and ignored.
 .PP
 Each line of the file can contain one of the following strings:
+.TP 0.5i
+.B ALIAS new-name  old-name
+Define an alias \fInew-name\fP which is equivalent to \fIold-name\fP.
+
+The ALIAS keyword is used to define additional names for compatibility
+reasons.  As there is no standard behind dictionary names, different
+products may use different names for the same attribute.  The ALIAS
+keyword allows you to add "site local" aliases, so that FreeRADIUS can
+read attributes from pre-existing configurations.
+
+These ALIASes are used when the server reads configuration files, or
+attributes from a database.  However, when the server prints attribute
+names, it always uses the ATTRIBUTE definition from the FreeRADIUS
+dictionary files/
+
 .TP 0.5i
 .B ATTRIBUTE name  oid  type [flags]
-Define a RADIUS attribute name to number mapping.
+Define an attribute name to number mapping.
 
 The \fIname\fP field is a printable field, taken from various
 specifications or vendor definitions.  It is most commonly used as a
index c9582106e4ad17ed565c8dec3c455d49097e52eb..5d438df72bb26b18bbe1f7f1bf656bc5491c4069 100755 (executable)
@@ -290,6 +290,20 @@ while (@ARGV) {
            next;
        }
 
+       #
+       #  Get ALIAS
+       #
+       if (/^ALIAS\s+([-\w]+)\s+(\w+)(.*)/) {
+           $name=$1;
+           $tabs = tabs(40, $name);
+
+           $ref = $2;
+           $stuff = $3;
+
+           push @output, "ALIAS\t\t$name$tabs$ref$stuff\n";
+           next;
+       }
+
        #
        #  VALUE attr name value
        #
index c02d37017d22deea4ccf0ff6d4e26bd535e25195..cd9914f6b6b3f07695fb0ae45b47800580dc247d 100644 (file)
@@ -518,6 +518,60 @@ static fr_dict_attr_t const *dict_gctx_unwind(dict_tokenize_ctx_t *ctx)
        return ctx->stack[ctx->stack_depth].da;
 }
 
+/*
+ *     Process the ALIAS command
+ */
+static int dict_read_process_alias(dict_tokenize_ctx_t *ctx, char **argv, int argc)
+{
+       fr_dict_attr_t const *da;
+
+       if (argc != 2) {
+               fr_strerror_printf("Invalid ALIAS syntax");
+               return -1;
+       }
+
+       /*
+        *      Dictionaries need to have real names, not shitty ones.
+        */
+       if (strncmp(argv[0], "Attr-", 5) == 0) {
+               fr_strerror_printf("Invalid ALIAS name");
+               return -1;
+       }
+
+       da = dict_attr_by_name(ctx->dict, argv[0]);
+       if (da) {
+               fr_strerror_printf("Attribute %s already exists", argv[0]);
+               return -1;
+       }
+
+       /*
+        *      The <src> can be a name.
+        */
+       da = dict_attr_by_name(ctx->dict, argv[1]);
+       if (!da) {
+               fr_strerror_printf("Attribute %s does not exist", argv[1]);
+               return -1;
+
+       }
+
+       /*
+        *      Note that we do NOT call fr_dict_attr_add() here.
+        *      When that function adds two equivalent attributes the
+        *      second one is prioritized for printing.  For ALIASes,
+        *      we want the first one to be prioritized.
+        */
+       da = dict_attr_alloc(ctx->dict->pool, da->parent, argv[0], da->attr, da->type, &da->flags);
+       if (!da) return -1;
+
+       if (!fr_hash_table_insert(ctx->dict->attributes_by_name, da)) {
+               fr_strerror_printf("Internal error storing attribute");
+               talloc_const_free(da);
+               return -1;
+       }
+
+       return 0;
+}
+
 /*
  *     Process the ATTRIBUTE command
  */
@@ -1761,6 +1815,15 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx,
                        return -1;
                }
 
+               /*
+                *      Perhaps this is an attribute.
+                */
+               if (strcasecmp(argv[0], "ALIAS") == 0) {
+                       if (dict_read_process_alias(ctx,
+                                                   argv + 1, argc - 1) == -1) goto error;
+                       continue;
+               }
+
                /*
                 *      Perhaps this is an attribute.
                 */