]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
also parse xlat conditions
authorAlan T. DeKok <aland@freeradius.org>
Mon, 20 Jun 2022 15:31:40 +0000 (11:31 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 20 Jun 2022 15:47:02 +0000 (11:47 -0400)
temporarily, so that we don't let the new code rot

src/lib/server/cf_file.c
src/lib/unlang/compile.c
src/lib/unlang/condition_priv.h

index 44579df9786c6aefe6279a01a4e70410952e8afd..507eef2888551e59f653ad110a29ea5123f37be0 100644 (file)
@@ -1146,10 +1146,16 @@ static int process_template(cf_stack_t *stack)
 
 static int cf_file_fill(cf_stack_t *stack);
 
+static const fr_sbuff_term_t if_terminals = FR_SBUFF_TERMS(
+       L(""),
+       L("{"),
+);
+
 static CONF_ITEM *process_if(cf_stack_t *stack)
 {
        ssize_t         slen = 0;
        fr_cond_t       *cond = NULL;
+       xlat_exp_head_t *head = NULL;
        fr_dict_t const *dict = NULL;
        CONF_SECTION    *cs;
        char            *p;
@@ -1158,6 +1164,7 @@ static CONF_ITEM *process_if(cf_stack_t *stack)
        CONF_SECTION    *parent = frame->current;
        char            *buff[4];
        tmpl_rules_t    t_rules;
+       fr_sbuff_parse_rules_t p_rules = { };
 
        /*
         *      Short names are nicer.
@@ -1175,6 +1182,9 @@ static CONF_ITEM *process_if(cf_stack_t *stack)
                        .allow_unknown = true
                }
        };
+
+       p_rules.terminals = &if_terminals;
+
        /*
         *      fr_cond_tokenize needs the current section, so we
         *      create it first.  We don't pass a name2, as it hasn't
@@ -1274,6 +1284,14 @@ static CONF_ITEM *process_if(cf_stack_t *stack)
                        slen = my_slen;
                        goto parse_error;
                }
+
+               my_slen = xlat_tokenize_expression(cs, &head, &FR_SBUFF_IN(buff[3], strlen(buff[3])), &p_rules, &t_rules);
+               fr_assert(my_slen > 0);
+       } else {
+               ssize_t my_slen;
+
+               my_slen = xlat_tokenize_expression(cs, &head, &FR_SBUFF_IN(buff[2], strlen(buff[2])), &p_rules, &t_rules);
+               fr_assert(my_slen > 0);
        }
 
        MEM(cs->name2 = talloc_typed_strdup(cs, buff[2]));
@@ -1294,6 +1312,7 @@ static CONF_ITEM *process_if(cf_stack_t *stack)
         *      the condition to the CONF_SECTION.
         */
        cf_data_add(cs, cond, NULL, false);
+       cf_data_add(cs, head, NULL, false);
        stack->ptr = ptr;
 
        cs->allow_unlang = true;
index e1e8161e2c3b7d80901f521b0cb9240c42dd0b8a..7c12ea0965162c601a8c71bfea26426538647f1b 100644 (file)
@@ -2301,7 +2301,7 @@ static unlang_t *compile_children(unlang_group_t *g, unlang_compile_t *unlang_ct
                case UNLANG_TYPE_IF:
                        was_if = true;
                        {
-                               unlang_group_t          *f;
+                               unlang_group_t  *f;
                                unlang_cond_t   *gext;
 
                                f = unlang_generic_to_group(single);
@@ -3038,6 +3038,8 @@ static unlang_t *compile_if_subsection(unlang_t *parent, unlang_compile_t *unlan
        unlang_cond_t           *gext;
 
        fr_cond_t               *cond;
+       xlat_exp_head_t         *head;
+       bool                    is_truthy, value;
 
        if (!cf_section_name2(cs)) {
                cf_log_err(cs, "'%s' without condition", unlang_ops[ext->type].name);
@@ -3047,10 +3049,28 @@ static unlang_t *compile_if_subsection(unlang_t *parent, unlang_compile_t *unlan
        cond = cf_data_value(cf_data_find(cs, fr_cond_t, NULL));
        fr_assert(cond != NULL);
 
+       head = cf_data_value(cf_data_find(cs, xlat_exp_head_t, NULL));
+       fr_assert(head != NULL);
+
+       /*
+        *      Resolve the xlat first.
+        */
+       if (xlat_resolve(head, NULL) < 0) {
+               cf_log_err(cs, "Failed resolving condition - %s", fr_strerror());
+               return NULL;
+       }
+
+       is_truthy = xlat_is_truthy(head, &value);
+
        if (cond->type == COND_TYPE_FALSE) {
                cf_log_debug_prefix(cs, "Skipping contents of '%s' as it is always 'false'",
                                    unlang_ops[ext->type].name);
+
+               c = compile_section(parent, unlang_ctx, cs, ext);
+               talloc_free(c);
+
                c = compile_empty(parent, unlang_ctx, cs, ext);
+
        } else {
                fr_cond_iter_t  iter;
                fr_cond_t       *leaf;
@@ -3082,6 +3102,7 @@ static unlang_t *compile_if_subsection(unlang_t *parent, unlang_compile_t *unlan
                }
 
                fr_cond_async_update(cond);
+
                c = compile_section(parent, unlang_ctx, cs, ext);
        }
        if (!c) return NULL;
@@ -3090,6 +3111,9 @@ static unlang_t *compile_if_subsection(unlang_t *parent, unlang_compile_t *unlan
        g = unlang_generic_to_group(c);
        gext = unlang_group_to_cond(g);
        gext->cond = cond;
+       gext->head = head;
+       gext->is_truthy = is_truthy;
+       gext->value = value;
 
        return c;
 }
index b856e9c6829548cf77eebc496b3e7b0a34008bf4..9bd0cf36cd706c3f32ee13390ee0bc854b23990c 100644 (file)
@@ -32,6 +32,9 @@ extern "C" {
 typedef struct {
        unlang_group_t  group;
        fr_cond_t       *cond;
+       xlat_exp_head_t *head;
+       bool            is_truthy;
+       bool            value;
 } unlang_cond_t;
 
 /** Cast a group structure to the cond keyword extension