.RE
.sp
..
-.TH dictionary 5 "14 May 2019"
+.TH dictionary 5 "09 Oct 2020"
.SH NAME
dictionary \- RADIUS dictionary file
.SH DESCRIPTION
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
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
*/
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.
*/