@@ -2487,13 +2487,14 @@ void map_debug_log(request_t *request, map_t const *map, fr_pair_t const *vp)
24872487 * @param[in] rhs of map
24882488 * @param[in] lhs_rules for parsing the LHS
24892489 * @param[in] rhs_rules for parsing the RHS
2490+ * @param[in] bare_word_only RHS is bare words, and nothing else.
24902491 * @return
24912492 * - 0 on success.
24922493 * - -1 on failure.
24932494 */
24942495int map_afrom_fields (TALLOC_CTX * ctx , map_t * * out , map_t * * parent_p , request_t * request ,
24952496 char const * lhs , char const * op_str , char const * rhs ,
2496- tmpl_rules_t const * lhs_rules , tmpl_rules_t const * rhs_rules )
2497+ tmpl_rules_t const * lhs_rules , tmpl_rules_t const * rhs_rules , bool bare_word_only )
24972498{
24982499 ssize_t slen ;
24992500 fr_token_t quote , op ;
@@ -2610,14 +2611,48 @@ int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, request_t *
26102611 }
26112612
26122613 /*
2613- * If we have a string, where the *entire* string is
2614- * quoted, then tokenize it that way,
2615- *
2616- * @todo - if the string starts with '(' OR '%' OR
2617- * doesn't begin with a quote, BUT contains spaces, then
2618- * parse it as an xlat expression!
2614+ * Try to figure out what we should do with the RHS.
26192615 */
2620- if (rhs [0 ] == '"' ) {
2616+ if ((map -> op == T_OP_CMP_TRUE ) || (map -> op == T_OP_CMP_FALSE )) {
2617+ /*
2618+ * These operators require a hard-coded string on the RHS.
2619+ */
2620+ if (strcmp (rhs , "ANY" ) != 0 ) {
2621+ fr_strerror_printf ("Invalid value %s for operator %s" , rhs , fr_tokens [map -> op ]);
2622+ goto error ;
2623+ }
2624+
2625+ if (tmpl_afrom_value_box (map , & map -> rhs , fr_box_strvalue ("ANY" ), false) < 0 ) goto error ;
2626+
2627+ } else if (bare_word_only ) {
2628+ fr_value_box_t * vb ;
2629+
2630+ /*
2631+ * No value, or no enum, parse it as a bare-word string.
2632+ */
2633+ if (!rhs [0 ] || !my_rules .enumv ) goto do_bare_word ;
2634+
2635+ MEM (vb = fr_value_box_alloc (map , my_rules .enumv -> type , my_rules .enumv ));
2636+
2637+ /*
2638+ * It MUST be the given data type.
2639+ */
2640+ slen = fr_value_box_from_str (map , vb , my_rules .enumv -> type , my_rules .enumv ,
2641+ rhs , strlen (rhs ), NULL , false);
2642+ if (slen <= 0 ) goto error ;
2643+
2644+ if (tmpl_afrom_value_box (map , & map -> rhs , vb , true) < 0 ) {
2645+ goto error ;
2646+ }
2647+
2648+ } else if (rhs [0 ] == '"' ) {
2649+ /*
2650+ * We've been asked to expand the RHS. Passwords like
2651+ *
2652+ * "%{Calling-Station-ID}"
2653+ *
2654+ * might not do what you want.
2655+ */
26212656 quote = T_DOUBLE_QUOTED_STRING ;
26222657 goto parse_quoted ;
26232658
@@ -2654,19 +2689,10 @@ int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, request_t *
26542689
26552690 /*
26562691 * Ignore any extra data after the string.
2692+ *
2693+ * @todo - this should likely be a parse error: we didn't parse the entire string!
26572694 */
26582695
2659- } else if ((map -> op == T_OP_CMP_TRUE ) || (map -> op == T_OP_CMP_FALSE )) {
2660- /*
2661- * These operators require a hard-coded string on the RHS.
2662- */
2663- if (strcmp (rhs , "ANY" ) != 0 ) {
2664- fr_strerror_printf ("Invalid value %s for operator %s" , rhs , fr_tokens [map -> op ]);
2665- goto error ;
2666- }
2667-
2668- if (tmpl_afrom_value_box (map , & map -> rhs , fr_box_strvalue ("ANY" ), false) < 0 ) goto error ;
2669-
26702696 } else if (rhs [0 ] == '&' ) {
26712697 /*
26722698 * No enums here.
@@ -2684,6 +2710,7 @@ int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, request_t *
26842710 }
26852711
26862712 } else if (!rhs [0 ] || !my_rules .enumv || (my_rules .enumv -> type == FR_TYPE_STRING )) {
2713+ do_bare_word :
26872714 quote = T_BARE_WORD ;
26882715
26892716 if (tmpl_attr_tail_da_is_structural (map -> lhs ) && !* rhs ) goto done ;
0 commit comments