]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add some additional xlats to expose attribute name, number and vendor
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 2 Jan 2015 05:04:54 +0000 (00:04 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 2 Jan 2015 05:11:06 +0000 (00:11 -0500)
src/main/xlat.c
src/tests/keywords/xlat-attr [new file with mode: 0644]

index 068473c6135541e282b0610e42d3df1653b4de53..30a7852e26489f7d388c47f927ca4f4fd60832c3 100644 (file)
@@ -288,6 +288,87 @@ static ssize_t xlat_tag(UNUSED void *instance, REQUEST *request,
        return snprintf(out, outlen, "%u", vp->tag);
 }
 
+/** Return the vendor of an attribute reference
+ *
+ */
+static ssize_t xlat_vendor(UNUSED void *instance, REQUEST *request,
+                          char const *fmt, char *out, size_t outlen)
+{
+       VALUE_PAIR *vp;
+       DICT_VENDOR *vendor;
+
+       while (isspace((int) *fmt)) fmt++;
+
+       if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
+               *out = '\0';
+               return 0;
+       }
+
+       vendor = dict_vendorbyvalue(vp->da->vendor);
+       if (!vendor) {
+               *out = '\0';
+               return 0;
+       }
+       strlcpy(out, vendor->name, outlen);
+
+       return vendor->length;
+}
+
+/** Return the vendor number of an attribute reference
+ *
+ */
+static ssize_t xlat_vendor_num(UNUSED void *instance, REQUEST *request,
+                              char const *fmt, char *out, size_t outlen)
+{
+       VALUE_PAIR *vp;
+
+       while (isspace((int) *fmt)) fmt++;
+
+       if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
+               *out = '\0';
+               return 0;
+       }
+
+       return snprintf(out, outlen, "%i", vp->da->vendor);
+}
+
+/** Return the attribute name of an attribute reference
+ *
+ */
+static ssize_t xlat_attr(UNUSED void *instance, REQUEST *request,
+                        char const *fmt, char *out, size_t outlen)
+{
+       VALUE_PAIR *vp;
+
+       while (isspace((int) *fmt)) fmt++;
+
+       if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
+               *out = '\0';
+               return 0;
+       }
+       strlcpy(out, vp->da->name, outlen);
+
+       return strlen(vp->da->name);
+}
+
+/** Return the attribute number of an attribute reference
+ *
+ */
+static ssize_t xlat_attr_num(UNUSED void *instance, REQUEST *request,
+                            char const *fmt, char *out, size_t outlen)
+{
+       VALUE_PAIR *vp;
+
+       while (isspace((int) *fmt)) fmt++;
+
+       if ((radius_get_vp(&vp, request, fmt) < 0) || !vp) {
+               *out = '\0';
+               return 0;
+       }
+
+       return snprintf(out, outlen, "%i", vp->da->attr);
+}
+
 /** Print out attribute info
  *
  * Prints out all instances of a current attribute, or all attributes in a list.
@@ -296,9 +377,6 @@ static ssize_t xlat_tag(UNUSED void *instance, REQUEST *request,
  * value. This is helpful to determine types for unknown attributes of long
  * passed vendors, or just crazy/broken NAS.
  *
- * It's also useful for exposing issues in the packet decoding functions, as in
- * some cases they get fed random garbage data.
- *
  * This expands to a zero length string.
  */
 static ssize_t xlat_debug_attr(UNUSED void *instance, REQUEST *request, char const *fmt,
@@ -383,7 +461,6 @@ static ssize_t xlat_debug_attr(UNUSED void *instance, REQUEST *request, char con
                        case PW_TYPE_COMBO_IP_ADDR:     /* Covered by IPv4 address IPv6 address */
                        case PW_TYPE_COMBO_IP_PREFIX:   /* Covered by IPv4 address IPv6 address */
                        case PW_TYPE_TIMEVAL:           /* Not a VALUE_PAIR type */
-
                                goto next_type;
 
                        default:
@@ -669,6 +746,10 @@ int xlat_register(char const *name, RAD_XLAT_FUNC func, RADIUS_ESCAPE_STRING esc
                XLAT_REGISTER(length);
                XLAT_REGISTER(hex);
                XLAT_REGISTER(tag);
+               XLAT_REGISTER(vendor);
+               XLAT_REGISTER(vendor_num);
+               XLAT_REGISTER(attr);
+               XLAT_REGISTER(attr_num);
                XLAT_REGISTER(string);
                XLAT_REGISTER(xlat);
                XLAT_REGISTER(module);
diff --git a/src/tests/keywords/xlat-attr b/src/tests/keywords/xlat-attr
new file mode 100644 (file)
index 0000000..d19495a
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# PRE: update
+#
+#  Check attribute info xlats work correctly
+#
+update {
+       control:Cleartext-Password := 'hello'
+       reply:Filter-Id := 'filter'
+}
+
+update request {
+       Reply-Message := 'foo'
+       FreeRADIUS-Proxied-To := 127.0.0.1
+}
+
+if ("%{attr:&FreeRADIUS-Proxied-To}" != 'FreeRADIUS-Proxied-To') {
+       update reply {
+               Filter-Id += 'Fail 0'
+       }
+}
+
+if ("%{attr_num:&FreeRADIUS-Proxied-To}" != 1) {
+       update reply {
+               Filter-Id += 'Fail 2'
+       }
+}
+
+if ("%{vendor:&FreeRADIUS-Proxied-To}" != 'FreeRADIUS') {
+       update reply {
+               Filter-Id += 'Fail 3'
+       }
+}
+
+if ("%{vendor_num:&FreeRADIUS-Proxied-To}" != 11344) {
+       update reply {
+               Filter-Id += 'Fail 4'
+       }
+}
+
+if ("%{attr:&Reply-Message}" != 'Reply-Message') {
+       update reply {
+               Filter-Id += 'Fail 5'
+       }
+}
+
+if ("%{attr_num:&Reply-Message}" != 18) {
+       update reply {
+               Filter-Id += 'Fail 6'
+       }
+}
+
+if ("%{vendor:&Reply-Message}" != '') {
+       update reply {
+               Filter-Id += 'Fail 7'
+       }
+}
+
+if ("%{vendor_num:&Reply-Message}" != 0) {
+       update reply {
+               Filter-Id += 'Fail 8'
+       }
+}