]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
require hard-coded RHS for legacy =* and !* operators.
authorAlan T. DeKok <aland@freeradius.org>
Sat, 18 Jan 2025 17:18:37 +0000 (12:18 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 18 Jan 2025 17:39:01 +0000 (12:39 -0500)
The recommendation for decades has been to use =*ANY or !*ANY.
We now make it official.

Without that check, the "no &" code will expect the RHS to be
an attribute reference, and will fail.

Update the documentation to match.

doc/antora/modules/howto/pages/modules/sql/index.adoc
doc/antora/modules/reference/pages/raddb/mods-available/attr_filter.adoc
doc/antora/modules/reference/pages/raddb/mods-config/files/users.adoc
raddb/mods-available/attr_filter
src/lib/server/map.c

index 0ade8dc3e4ec767dd99dc7014cd34f87de931d2a..88af5a751dc2d20a744374b68819e2053f7c1d59 100644 (file)
@@ -287,19 +287,19 @@ Not allowed as a reply item.
 
 === =*
 
-e.g: `Attribute =* Value`
+e.g: `Attribute =* ANY`
 
 As a check item, it matches if the request contains the named
-attribute, no matter what the value is.
+attribute.  The right-hand side must be the word `ANY`.
 
 Not allowed as a reply item.
 
 === !*
 
-e.g: `Attribute !* Value`
+e.g: `Attribute !* ANY`
 
 As a check item, it matches if the request does not contain
-the named attribute, no matter what the value is.
+the named attribute.  The right-hand side must be the word `ANY`.
 
 Not allowed as a reply item.
 
index 08625b02f594b502e94f19b2004bd5117fc954cc..57829224edd0b2fe7206350b41df92f47d4be365 100644 (file)
@@ -28,7 +28,9 @@ The operators and their purpose in defining the rules are as follows:
              output A/V Pairs. If the attribute exists, it is overwritten.
 | ==       | Equal, value must match exactly.
 | =*       | Always Equal, allow all values for the specified attribute.
+             The right-hand side must be the word `ANY`.
 | !*       | Never Equal, disallow all values for the specified attribute.
+             The right-hand side must be the word `ANY`.
              (This is redundant, as any A/V Pair not explicitly permitted
              will be dropped).
 | !=       | Not Equal, value must not match.
index ddacbd5f66782fa267ff1c6328b83deae99d7ca5..44b542da3fdd086a5e3759065d5f0217dd114137 100644 (file)
@@ -269,8 +269,8 @@ As a special case for compatibility with previous versions, the `users` file als
 [cols="10%,90%"]
 |=====
 | Operator | Description
-| =*       | Matches if the attribute exists, no matter what the value is.
-| !*       | Matches if the attribute does not exist, no matter what the value is.
+| =*       | Matches if the attribute exists.  The right-hand side must be the word `ANY`.
+| !*       | Matches if the attribute does not exist.  The right-hand side must be the word `ANY`.
 |=====
 
 Due to limitations of the `users` file format, a value must be specified for these additional comparison operators.  The best practice is to use a meaningless special value `ANY`, such as `Framed-IP-Address !* ANY`.
index 1b8e396ca2700571130db6effe184ac347f2cd49..ef757da3d2c46873a0ead9f7bfc6cd7ee78d5225 100644 (file)
@@ -31,7 +31,9 @@
 #               output A/V Pairs. If the attribute exists, it is overwritten.
 #  | ==       | Equal, value must match exactly.
 #  | =*       | Always Equal, allow all values for the specified attribute.
+#               The right-hand side must be the word `ANY`.
 #  | !*       | Never Equal, disallow all values for the specified attribute.
+#               The right-hand side must be the word `ANY`.
 #               (This is redundant, as any A/V Pair not explicitly permitted
 #               will be dropped).
 #  | !=       | Not Equal, value must not match.
index 7d9c49a868a34a5de1cfd267e1bfecc533d1f3ba..5a784885f04a0b5fbae5e71b35f7a3aaa8d399a1 100644 (file)
@@ -643,14 +643,27 @@ parse_rhs:
                break;
 
        default:
-               if (!p_rules) p_rules = &value_parse_rules_bareword_quoted;
+               if ((map->op == T_OP_CMP_TRUE) || (map->op == T_OP_CMP_FALSE)) {
+                       /*
+                        *      These operators require a hard-coded string on the RHS.
+                        */
+                       if (fr_sbuff_adv_past_str_literal(&our_in, "ANY") <= 0) {
+                               fr_strerror_printf("Invalid value for %s", fr_tokens[map->op]);
+                               goto error;
+                       }
 
-               /*
-                *      Use the RHS termination rules ONLY for bare
-                *      words.  For quoted strings we already know how
-                *      to terminate the input string.
-                */
-               slen = tmpl_afrom_substr(map, &map->rhs, &our_in, token, p_rules, rhs_rules);
+                       (void) tmpl_afrom_value_box(map, &map->rhs, fr_box_strvalue("ANY"), false);
+
+               } else {
+                       if (!p_rules) p_rules = &value_parse_rules_bareword_quoted;
+
+                       /*
+                        *      Use the RHS termination rules ONLY for bare
+                        *      words.  For quoted strings we already know how
+                        *      to terminate the input string.
+                        */
+                       slen = tmpl_afrom_substr(map, &map->rhs, &our_in, token, p_rules, rhs_rules);
+               }
                break;
        }
        if (!map->rhs) goto error_adj;
@@ -2596,6 +2609,17 @@ int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, request_t *
                 *      Ignore any extra data after the string.
                 */
 
+       } else if ((map->op == T_OP_CMP_TRUE) || (map->op == T_OP_CMP_FALSE)) {
+               /*
+                *      These operators require a hard-coded string on the RHS.
+                */
+               if (strcmp(rhs, "ANY") != 0) {
+                       fr_strerror_printf("Invalid value for %s", fr_tokens[map->op]);
+                       goto error;
+               }
+
+               if (tmpl_afrom_value_box(map, &map->rhs, fr_box_strvalue("ANY"), false) < 0) goto error;
+
        } else if (rhs[0] == '&') {
                /*
                 *      No enums here.