and regularize the names.
*** xref:mods-available/detail.log.adoc[Detail Module (Log Sample)]
*** xref:mods-available/dhcp_sqlippool.adoc[DHCP SQL-IP-Pool Module]
*** xref:mods-available/dhcpv4.adoc[DHCPv4 Module]
+*** xref:mods-available/dict.adoc[Dict Module]
*** xref:mods-available/digest.adoc[Digest Module]
*** xref:mods-available/eap.adoc[EAP Module]
*** xref:mods-available/eap_inner.adoc[EAP/Inner Module]
--- /dev/null
+
+
+
+
+= Dict Module
+
+The `dict` module registers expansions which query the dictionaries.
+
+
+## Expansions
+
+The following expansions allow querying the dictionaries.
+
+### %dict.attr(_<string>_)
+
+Takes an attribute name, and returns the canonicalized name of the attribute.
+
+If the attribute does not exist, nothing is returned.
+
+.Return: _string_
+
+### %dict.attr.by.num(_<uint32>_)
+
+Takes an attribute number, and returns the canonicalized name of the attribute.
+
+If the attribute does not exist, nothing is returned.
+
+This function is useful only for "top level" attributes such as `link:https://freeradius.org/rfc/rfc2865.html#User-Name[User-Name]`.
+Where the attribute is nested, use `%dict.attr.by.oid()` instead.
+
+.Return: _string_
+
+### %dict.attr.by.oid(_<string>_)
+
+Takes a full OID reference (e.g. `26.9.1`), and returns the name of
+the attribute.
+
+If the attribute does not exist, nothing is returned.
+
+.Return: _string_
+
+### %dict.attr.num(_<string>_)
+
+Takes an attribute name, and returns the number of the attribute.
+
+If the attribute does not exist, nothing is returned.
+
+Note that only the _final_ attribute number is returned. For example, the OID
+for `Vendor-Specific.Cisco.AVPair` is `26.9.1`. This function will return
+`1`, and not the full OID.
+
+.Return: _uint32_
+
+### %dict.attr.type(_<string>_)
+
+Takes an attribute name, and returns the data type of the attribute.
+
+If the attribute does not exist, nothing is returned.
+
+.Return: _string_
+
+### %dict.vendor(_<string>_)
+
+Takes an vendor name, and returns the canonicalized name of the vendor.
+
+If the vendor does not exist, nothing is returned.
+
+.Return: _string_
+
+### %dict.vendor.by.num(_<uint32>_)
+
+Takes an vendor number, and returns the canonicalized name of the vendor.
+
+If the vendor does not exist, nothing is returned.
+
+.Return: _string_
+
+
+
+## Configuration Settings
+
+This module takes no configuration.
+
+
+
+== Default Configuration
+
+```
+dict {
+}
+```
--- /dev/null
+# -*- text -*-
+#
+#
+# $Id$
+
+#######################################################################
+#
+# = Dict Module
+#
+# The `dict` module registers expansions which query the dictionaries.
+
+#
+# ## Expansions
+#
+# The following expansions allow querying the dictionaries.
+#
+# ### %dict.attr(_<string>_)
+#
+# Takes an attribute name, and returns the canonicalized name of the attribute.
+#
+# If the attribute does not exist, nothing is returned.
+#
+# .Return: _string_
+#
+# ### %dict.attr.by.num(_<uint32>_)
+#
+# Takes an attribute number, and returns the canonicalized name of the attribute.
+#
+# If the attribute does not exist, nothing is returned.
+#
+# This function is useful only for "top level" attributes such as `User-Name`.
+# Where the attribute is nested, use `%dict.attr.by.oid()` instead.
+#
+# .Return: _string_
+#
+# ### %dict.attr.by.oid(_<string>_)
+#
+# Takes a full OID reference (e.g. `26.9.1`), and returns the name of
+# the attribute.
+#
+# If the attribute does not exist, nothing is returned.
+#
+# .Return: _string_
+#
+# ### %dict.attr.num(_<string>_)
+#
+# Takes an attribute name, and returns the number of the attribute.
+#
+# If the attribute does not exist, nothing is returned.
+#
+# Note that only the _final_ attribute number is returned. For example, the OID
+# for `Vendor-Specific.Cisco.AVPair` is `26.9.1`. This function will return
+# `1`, and not the full OID.
+#
+# .Return: _uint32_
+#
+# ### %dict.attr.type(_<string>_)
+#
+# Takes an attribute name, and returns the data type of the attribute.
+#
+# If the attribute does not exist, nothing is returned.
+#
+# .Return: _string_
+#
+# ### %dict.vendor(_<string>_)
+#
+# Takes an vendor name, and returns the canonicalized name of the vendor.
+#
+# If the vendor does not exist, nothing is returned.
+#
+# .Return: _string_
+#
+# ### %dict.vendor.by.num(_<uint32>_)
+#
+# Takes an vendor number, and returns the canonicalized name of the vendor.
+#
+# If the vendor does not exist, nothing is returned.
+#
+# .Return: _string_
+#
+
+#
+# ## Configuration Settings
+#
+# This module takes no configuration.
+#
+dict {
+
+}
return XLAT_ACTION_DONE;
}
+/** Return the data type of an attribute reference
+ *
+ * @ingroup xlat_functions
+ */
+static xlat_action_t xlat_attr_type(TALLOC_CTX *ctx, fr_dcursor_t *out,
+ UNUSED xlat_ctx_t const *xctx,
+ request_t *request, fr_value_box_list_t *in)
+{
+ fr_pair_t *vp;
+ fr_value_box_t *attr = fr_value_box_list_head(in);
+ fr_value_box_t *vb;
+
+ if ((xlat_fmt_get_vp(&vp, request, attr->vb_strvalue) < 0) || !vp) return XLAT_ACTION_FAIL;
+
+ MEM(vb = fr_value_box_alloc_null(ctx));
+
+ fr_value_box_strdup(vb, vb, vp->da, fr_type_to_str(vp->vp_type), false);
+ fr_dcursor_append(out, vb);
+ return XLAT_ACTION_DONE;
+}
+
#define XLAT_REGISTER(_name, _func, _type, _args) \
if (unlikely(!(xlat = xlat_func_register(NULL, _name, _func, _type)))) return -1; \
xlat_func_args_set(xlat, _args)
{
xlat_t *xlat;
- XLAT_REGISTER("attr_by_num", xlat_dict_attr_by_num, FR_TYPE_STRING, xlat_dict_attr_by_num_args);
- XLAT_REGISTER("attr_by_oid", xlat_dict_attr_by_oid, FR_TYPE_STRING, xlat_dict_attr_by_oid_args);
- XLAT_REGISTER("vendor", xlat_vendor, FR_TYPE_STRING, xlat_vendor_args);
- XLAT_REGISTER("vendor_num", xlat_vendor_num, FR_TYPE_UINT32, xlat_vendor_num_args);
- XLAT_REGISTER("attr", xlat_attr, FR_TYPE_STRING, xlat_attr_args);
- XLAT_REGISTER("attr_num", xlat_attr_num, FR_TYPE_UINT32, xlat_attr_num_args);
-
+ XLAT_REGISTER("dict.attr.by.num", xlat_dict_attr_by_num, FR_TYPE_STRING, xlat_dict_attr_by_num_args);
+ XLAT_REGISTER("dict.attr.by.oid", xlat_dict_attr_by_oid, FR_TYPE_STRING, xlat_dict_attr_by_oid_args);
+ XLAT_REGISTER("dict.vendor", xlat_vendor, FR_TYPE_STRING, xlat_vendor_args);
+ XLAT_REGISTER("dict.vendor.num", xlat_vendor_num, FR_TYPE_UINT32, xlat_vendor_num_args);
+ XLAT_REGISTER("dict.attr", xlat_attr, FR_TYPE_STRING, xlat_attr_args);
+ XLAT_REGISTER("dict.attr.num", xlat_attr_num, FR_TYPE_UINT32, xlat_attr_num_args);
+ XLAT_REGISTER("dict.attr.type", xlat_attr_type, FR_TYPE_STRING, xlat_attr_args);
return 0;
}
static void mod_unload(void)
{
- xlat_func_unregister("attr_by_num");
- xlat_func_unregister("attr_by_oid");
- xlat_func_unregister("vendor");
- xlat_func_unregister("vendor_num");
- xlat_func_unregister("attr");
- xlat_func_unregister("attr_num");
+ xlat_func_unregister("dict.attr.by.num");
+ xlat_func_unregister("dict.attr.by.oid");
+ xlat_func_unregister("dict.vendor");
+ xlat_func_unregister("dict.vendor.num");
+ xlat_func_unregister("dict.attr");
+ xlat_func_unregister("dict.attr.num");
}
extern module_rlm_t rlm_dict;
&Reply-Message := 'foo'
-if ("%(attr_by_num:1)" != 'User-Name') {
+if (%dict.attr.by.num(1) != 'User-Name') {
test_fail
}
-if ("%(attr_by_oid:1)" != 'User-Name') {
+if (%dict.attr.by.oid(1) != 'User-Name') {
test_fail
}
# Should fail
-if ("%(attr_by_oid:26)" != 'Vendor-Specific') {
+if (%dict.attr.by.oid(26) != 'Vendor-Specific') {
test_fail
}
# Should fail
-if ("%(attr_by_oid:26.11344)" != 'FreeRADIUS') {
+if (%dict.attr.by.oid(26.11344) != 'FreeRADIUS') {
test_fail
}
-if ("%(attr_by_oid:26.11344.1)" != 'Proxied-To') {
+if (%dict.attr.by.oid(26.11344.1) != 'Proxied-To') {
test_fail
}
-if ("%(attr:Vendor-Specific.FreeRADIUS.Proxied-To)" != 'Proxied-To') {
+if (%dict.attr('Vendor-Specific.FreeRADIUS.Proxied-To') != 'Proxied-To') {
test_fail
}
-if ("%(attr_num:Vendor-Specific.FreeRADIUS.Proxied-To)" != 1) {
+if (%dict.attr.num('Vendor-Specific.FreeRADIUS.Proxied-To') != 1) {
test_fail
}
-if ("%(vendor:Vendor-Specific.FreeRADIUS.Proxied-To)" != 'FreeRADIUS') {
+if (%dict.vendor('Vendor-Specific.FreeRADIUS.Proxied-To') != 'FreeRADIUS') {
test_fail
}
-if ("%(vendor_num:Vendor-Specific.FreeRADIUS.Proxied-To)" != 11344) {
+if (%dict.vendor.num('Vendor-Specific.FreeRADIUS.Proxied-To') != 11344) {
test_fail
}
-if ("%(attr:Reply-Message)" != 'Reply-Message') {
+if (%dict.attr('Reply-Message') != 'Reply-Message') {
test_fail
}
-if ("%(attr_num:Reply-Message)" != 18) {
+if (%dict.attr.num('Reply-Message') != 18) {
test_fail
}
-if ("%(vendor:Reply-Message)" != '') {
+if %dict.vendor('Reply-Message') {
test_fail
}
-if ("%(vendor_num:Reply-Message)" != 0) {
+if (%dict.vendor.num('Reply-Message') != 0) {
+ test_fail
+}
+
+if (%dict.attr.type ('User-Name') != 'string') {
+ test_fail
+}
+
+if (%dict.attr.type ('Vendor-Specific') != 'vendor') {
test_fail
}