From 637916b93f12523efcc6d8355708a00192eb80ed Mon Sep 17 00:00:00 2001 From: Arran Cudbard-Bell Date: Wed, 19 Jan 2022 10:20:01 -0500 Subject: [PATCH] Split tmpl rules --- src/bin/unit_test_attribute.c | 73 +++++++------- src/bin/unit_test_map.c | 6 +- src/lib/io/master.c | 11 ++- src/lib/ldap/map.c | 20 ++-- src/lib/redis/redis.c | 2 +- src/lib/server/cf_file.c | 18 ++-- src/lib/server/cf_parse.c | 10 +- src/lib/server/cond_eval.c | 26 ++--- src/lib/server/cond_tokenize.c | 26 ++--- src/lib/server/map.c | 133 +++++++++++++------------- src/lib/server/map_async.c | 17 ++-- src/lib/server/tmpl.h | 54 +++++++---- src/lib/server/tmpl_dcursor.c | 4 +- src/lib/server/tmpl_eval.c | 2 +- src/lib/server/tmpl_tokenize.c | 84 ++++++++-------- src/lib/server/users_file.c | 40 ++++---- src/lib/server/virtual_servers.c | 4 +- src/lib/unlang/compile.c | 102 +++++++++++--------- src/lib/unlang/edit.c | 2 +- src/lib/unlang/xlat.h | 11 ++- src/lib/unlang/xlat_builtin.c | 28 +++--- src/lib/unlang/xlat_eval.c | 7 +- src/lib/unlang/xlat_expr.c | 12 +-- src/lib/unlang/xlat_priv.h | 6 +- src/lib/unlang/xlat_tokenize.c | 24 ++--- src/modules/rlm_cache/rlm_cache.c | 6 +- src/modules/rlm_cache/serialize.c | 8 +- src/modules/rlm_csv/rlm_csv.c | 4 +- src/modules/rlm_exec/rlm_exec.c | 8 +- src/modules/rlm_expr/rlm_expr.c | 4 +- src/modules/rlm_json/rlm_json.c | 4 +- src/modules/rlm_ldap/rlm_ldap.c | 4 +- src/modules/rlm_linelog/rlm_linelog.c | 8 +- src/modules/rlm_python/rlm_python.c | 2 +- src/modules/rlm_radius/rlm_radius.c | 4 +- src/modules/rlm_rest/rest.c | 4 +- src/modules/rlm_smtp/rlm_smtp.c | 18 ++-- 37 files changed, 436 insertions(+), 360 deletions(-) diff --git a/src/bin/unit_test_attribute.c b/src/bin/unit_test_attribute.c index c05e736c1b..4ce1ed3050 100644 --- a/src/bin/unit_test_attribute.c +++ b/src/bin/unit_test_attribute.c @@ -956,8 +956,8 @@ static int dictionary_load_common(command_result_t *result, command_file_ctx_t * /* * Decrease ref count if we're loading in a new dictionary */ - if (cc->tmpl_rules.dict_def) { - if (fr_dict_const_free(&cc->tmpl_rules.dict_def, __FILE__) < 0) return -1; + if (cc->tmpl_rules.attr.dict_def) { + if (fr_dict_const_free(&cc->tmpl_rules.attr.dict_def, __FILE__) < 0) return -1; } q = strchr(in, ' '); @@ -974,12 +974,12 @@ static int dictionary_load_common(command_result_t *result, command_file_ctx_t * talloc_free(tmp); if (ret < 0) RETURN_COMMAND_ERROR(); - cc->tmpl_rules.dict_def = dict; + cc->tmpl_rules.attr.dict_def = dict; /* * Dump the dictionary if we're in super debug mode */ - if (fr_debug_lvl > 5) fr_dict_debug(cc->tmpl_rules.dict_def); + if (fr_debug_lvl > 5) fr_dict_debug(cc->tmpl_rules.attr.dict_def); RETURN_OK(0); } @@ -1133,7 +1133,7 @@ static size_t command_allow_unresolved(command_result_t *result, command_file_ct { fr_sbuff_t our_in = FR_SBUFF_IN(in, inlen); - if (fr_sbuff_out_bool(&cc->tmpl_rules.allow_unresolved, &our_in) == 0) { + if (fr_sbuff_out_bool(&cc->tmpl_rules.attr.allow_unresolved, &our_in) == 0) { fr_strerror_printf("Invalid boolean value, must be \"yes\" or \"no\""); RETURN_COMMAND_ERROR(); } @@ -1149,7 +1149,7 @@ static size_t command_normalise_attribute(command_result_t *result, command_file { fr_pair_list_t head; ssize_t slen; - fr_dict_t const *dict = cc->tmpl_rules.dict_def ? cc->tmpl_rules.dict_def : cc->config->dict; + fr_dict_t const *dict = cc->tmpl_rules.attr.dict_def ? cc->tmpl_rules.attr.dict_def : cc->config->dict; fr_pair_list_init(&head); @@ -1516,7 +1516,7 @@ static size_t command_decode_pair(command_result_t *result, command_file_ctx_t * * point to produce fr_pair_ts. */ while (to_dec < to_dec_end) { - slen = tp->func(cc->tmp_ctx, &head, fr_dict_root(cc->tmpl_rules.dict_def ? cc->tmpl_rules.dict_def : cc->config->dict), + slen = tp->func(cc->tmp_ctx, &head, fr_dict_root(cc->tmpl_rules.attr.dict_def ? cc->tmpl_rules.attr.dict_def : cc->config->dict), (uint8_t *)to_dec, (to_dec_end - to_dec), decode_ctx); cc->last_ret = slen; if (slen <= 0) { @@ -1693,7 +1693,7 @@ static size_t command_dictionary_attribute_parse(command_result_t *result, comma static size_t command_dictionary_dump(command_result_t *result, command_file_ctx_t *cc, UNUSED char *data, size_t data_used, UNUSED char *in, UNUSED size_t inlen) { - fr_dict_debug(cc->tmpl_rules.dict_def ? cc->tmpl_rules.dict_def : cc->config->dict); + fr_dict_debug(cc->tmpl_rules.attr.dict_def ? cc->tmpl_rules.attr.dict_def : cc->config->dict); /* * Don't modify the contents of the data buffer @@ -1851,7 +1851,7 @@ static size_t command_encode_pair(command_result_t *result, command_file_ctx_t * RETURN_COMMAND_ERROR(); } - dict = cc->tmpl_rules.dict_def ? cc->tmpl_rules.dict_def : cc->config->dict; + dict = cc->tmpl_rules.attr.dict_def ? cc->tmpl_rules.attr.dict_def : cc->config->dict; if (fr_pair_list_afrom_str(cc->tmp_ctx, fr_dict_root(dict), p, in + inlen - p, &head) != T_EOL) { CLEAR_TEST_POINT(cc); @@ -1884,7 +1884,7 @@ static size_t command_encode_pair(command_result_t *result, command_file_ctx_t * for (vp = fr_pair_dcursor_iter_init(&cursor, &head, tp->next_encodable ? tp->next_encodable : fr_proto_next_encodable, - cc->tmpl_rules.dict_def ? cc->tmpl_rules.dict_def : cc->config->dict); + cc->tmpl_rules.attr.dict_def ? cc->tmpl_rules.attr.dict_def : cc->config->dict); vp; vp = fr_dcursor_current(&cursor)) { slen = tp->func(&FR_DBUFF_TMP(enc_p, enc_end), &cursor, encode_ctx); @@ -2010,7 +2010,7 @@ static size_t command_encode_proto(command_result_t *result, command_file_ctx_t RETURN_COMMAND_ERROR(); } - dict = cc->tmpl_rules.dict_def ? cc->tmpl_rules.dict_def : cc->config->dict; + dict = cc->tmpl_rules.attr.dict_def ? cc->tmpl_rules.attr.dict_def : cc->config->dict; if (fr_pair_list_afrom_str(cc->tmp_ctx, fr_dict_root(dict), p, in + inlen - p, &head) != T_EOL) { CLEAR_TEST_POINT(cc); @@ -2141,7 +2141,7 @@ static size_t command_load_dictionary(command_result_t *result, command_file_ctx dir = cc->path; } - ret = fr_dict_read(UNCONST(fr_dict_t *, cc->tmpl_rules.dict_def), dir, name); + ret = fr_dict_read(UNCONST(fr_dict_t *, cc->tmpl_rules.attr.dict_def), dir, name); talloc_free(tmp); if (ret < 0) RETURN_COMMAND_ERROR(); @@ -2295,7 +2295,7 @@ static size_t command_pair(command_result_t *result, command_file_ctx_t *cc, fr_pair_list_init(&head); ctx.ctx = cc->tmp_ctx; - ctx.parent = fr_dict_root(cc->tmpl_rules.dict_def); + ctx.parent = fr_dict_root(cc->tmpl_rules.attr.dict_def); ctx.list = &head; p = in; @@ -2384,45 +2384,45 @@ typedef ssize_t(*command_tmpl_rule_func)(tmpl_rules_t *rules, fr_sbuff_t *value) static ssize_t command_tmpl_rule_allow_foreign(tmpl_rules_t *rules, fr_sbuff_t *value) { - return fr_sbuff_out_bool(&rules->allow_foreign, value); + return fr_sbuff_out_bool(&rules->attr.allow_foreign, value); } static ssize_t command_tmpl_rule_allow_unknown(tmpl_rules_t *rules, fr_sbuff_t *value) { - return fr_sbuff_out_bool(&rules->allow_unknown, value); + return fr_sbuff_out_bool(&rules->attr.allow_unknown, value); } static ssize_t command_tmpl_rule_allow_unresolved(tmpl_rules_t *rules, fr_sbuff_t *value) { - return fr_sbuff_out_bool(&rules->allow_unresolved, value); + return fr_sbuff_out_bool(&rules->attr.allow_unresolved, value); } static ssize_t command_tmpl_rule_attr_parent(tmpl_rules_t *rules, fr_sbuff_t *value) { return fr_dict_attr_by_oid_substr(NULL, - &rules->attr_parent, - rules->dict_def ? fr_dict_root(rules->dict_def) : - fr_dict_root(fr_dict_internal()), + &rules->attr.parent, + rules->attr.dict_def ? fr_dict_root(rules->attr.dict_def) : + fr_dict_root(fr_dict_internal()), value, NULL); } static ssize_t command_tmpl_rule_disallow_internal(tmpl_rules_t *rules, fr_sbuff_t *value) { - return fr_sbuff_out_bool(&rules->disallow_internal, value); + return fr_sbuff_out_bool(&rules->attr.disallow_internal, value); } static ssize_t command_tmpl_rule_disallow_qualifiers(tmpl_rules_t *rules, fr_sbuff_t *value) { - return fr_sbuff_out_bool(&rules->disallow_qualifiers, value); + return fr_sbuff_out_bool(&rules->attr.disallow_qualifiers, value); } static ssize_t command_tmpl_rule_list_def(tmpl_rules_t *rules, fr_sbuff_t *value) { ssize_t slen; - fr_sbuff_out_by_longest_prefix(&slen, &rules->list_def, pair_list_table, value, PAIR_LIST_UNKNOWN); + fr_sbuff_out_by_longest_prefix(&slen, &rules->attr.list_def, pair_list_table, value, PAIR_LIST_UNKNOWN); - if (rules->list_def == PAIR_LIST_UNKNOWN) { + if (rules->attr.list_def == PAIR_LIST_UNKNOWN) { fr_strerror_printf("Invalid list specifier \"%pV\"", fr_box_strvalue_len(fr_sbuff_current(value), fr_sbuff_remaining(value))); } @@ -2434,9 +2434,9 @@ static ssize_t command_tmpl_rule_request_def(tmpl_rules_t *rules, fr_sbuff_t *va { ssize_t slen; - fr_sbuff_out_by_longest_prefix(&slen, &rules->request_def, tmpl_request_ref_table, value, REQUEST_UNKNOWN); + fr_sbuff_out_by_longest_prefix(&slen, &rules->attr.request_def, tmpl_request_ref_table, value, REQUEST_UNKNOWN); - if (rules->request_def == REQUEST_UNKNOWN) { + if (rules->attr.request_def == REQUEST_UNKNOWN) { fr_strerror_printf("Invalid request specifier \"%pV\"", fr_box_strvalue_len(fr_sbuff_current(value), fr_sbuff_remaining(value))); } @@ -2610,9 +2610,10 @@ static size_t command_xlat_normalise(command_result_t *result, command_file_ctx_ fr_sbuff_parse_rules_t p_rules = { .escapes = &fr_value_unescape_double }; dec_len = xlat_tokenize(cc->tmp_ctx, &head, NULL, &FR_SBUFF_IN(in, input_len), &p_rules, - &(tmpl_rules_t) { - .dict_def = cc->tmpl_rules.dict_def ? cc->tmpl_rules.dict_def : cc->config->dict, - .allow_unresolved = cc->tmpl_rules.allow_unresolved + &(tmpl_attr_rules_t) { + .dict_def = cc->tmpl_rules.attr.dict_def ? + cc->tmpl_rules.attr.dict_def : cc->config->dict, + .allow_unresolved = cc->tmpl_rules.attr.allow_unresolved }); if (dec_len <= 0) { fr_strerror_printf_push_head("ERROR offset %d", (int) -dec_len); @@ -2642,9 +2643,10 @@ static size_t command_xlat_expr(command_result_t *result, command_file_ctx_t *cc // fr_sbuff_parse_rules_t p_rules = { .escapes = &fr_value_unescape_double }; dec_len = xlat_tokenize_expression(cc->tmp_ctx, &head, NULL, &FR_SBUFF_IN(in, input_len), NULL, - &(tmpl_rules_t) { - .dict_def = cc->tmpl_rules.dict_def ? cc->tmpl_rules.dict_def : cc->config->dict, - .allow_unresolved = cc->tmpl_rules.allow_unresolved + &(tmpl_attr_rules_t) { + .dict_def = cc->tmpl_rules.attr.dict_def ? + cc->tmpl_rules.attr.dict_def : cc->config->dict, + .allow_unresolved = cc->tmpl_rules.attr.allow_unresolved }); if (dec_len <= 0) { fr_strerror_printf_push_head("ERROR offset %d", (int) -dec_len); @@ -2679,9 +2681,10 @@ static size_t command_xlat_argv(command_result_t *result, command_file_ctx_t *cc slen = xlat_tokenize_argv(cc->tmp_ctx, &head, NULL, &FR_SBUFF_IN(in, input_len), NULL, - &(tmpl_rules_t) { - .dict_def = cc->tmpl_rules.dict_def ? cc->tmpl_rules.dict_def : cc->config->dict, - .allow_unresolved = cc->tmpl_rules.allow_unresolved + &(tmpl_attr_rules_t) { + .dict_def = cc->tmpl_rules.attr.dict_def ? + cc->tmpl_rules.attr.dict_def : cc->config->dict, + .allow_unresolved = cc->tmpl_rules.attr.allow_unresolved }); if (slen <= 0) { fr_strerror_printf_push_head("ERROR offset %d", (int) -slen); @@ -3218,7 +3221,7 @@ finish: /* * Free any residual resources we loaded. */ - if (cc && (fr_dict_const_free(&cc->tmpl_rules.dict_def, __FILE__) < 0)) { + if (cc && (fr_dict_const_free(&cc->tmpl_rules.attr.dict_def, __FILE__) < 0)) { fr_perror("unit_test_attribute"); ret = -1; } diff --git a/src/bin/unit_test_map.c b/src/bin/unit_test_map.c index 92a3f18d9d..82df15ec0b 100644 --- a/src/bin/unit_test_map.c +++ b/src/bin/unit_test_map.c @@ -82,8 +82,10 @@ static int process_file(char const *filename) main_config_t *config; tmpl_rules_t parse_rules = { - .dict_def = dict_radius, - .allow_foreign = false, /* tests are in the RADIUS dictionary */ + .attr = { + .dict_def = dict_radius, + .allow_foreign = false, /* tests are in the RADIUS dictionary */ + } }; map_list_init(&list); diff --git a/src/lib/io/master.c b/src/lib/io/master.c index 8a2238dccf..a92848cab4 100644 --- a/src/lib/io/master.c +++ b/src/lib/io/master.c @@ -2669,15 +2669,16 @@ static int mod_instantiate(void *instance, CONF_SECTION *conf) * Maybe we should? */ if (app_process->compile_list) { - tmpl_rules_t parse_rules; - - memset(&parse_rules, 0, sizeof(parse_rules)); - parse_rules.dict_def = virtual_server_namespace(cf_section_name2(inst->server_cs)); + tmpl_rules_t parse_rules = { + .attr = { + .dict_def = virtual_server_namespace(cf_section_name2(inst->server_cs)) + } + }; if (virtual_server_compile_sections(inst->server_cs, app_process->compile_list, &parse_rules, inst->dynamic_submodule->data) < 0) { return -1; - } + }; } if (app_process->instantiate && (app_process->instantiate(inst->dynamic_submodule->data, conf) < 0)) { diff --git a/src/lib/ldap/map.c b/src/lib/ldap/map.c index c5a8faee22..1938bb5fe3 100644 --- a/src/lib/ldap/map.c +++ b/src/lib/ldap/map.c @@ -65,15 +65,19 @@ int fr_ldap_map_getvalue(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *reques char *attr_str; tmpl_rules_t lhs_rules = { - .dict_def = request->dict, - .request_def = tmpl_request(map->lhs), - .list_def = tmpl_list(map->lhs), - .prefix = TMPL_ATTR_REF_PREFIX_AUTO, + .attr = { + .dict_def = request->dict, + .request_def = tmpl_request(map->lhs), + .list_def = tmpl_list(map->lhs), + .prefix = TMPL_ATTR_REF_PREFIX_AUTO + }, .at_runtime = true, }; tmpl_rules_t rhs_rules = { - .dict_def = request->dict, + .attr = { + .dict_def = request->dict + }, .at_runtime = true, }; @@ -369,8 +373,10 @@ int fr_ldap_map_do(request_t *request, LDAP *handle, char *value; tmpl_rules_t parse_rules = { - .dict_def = request->dict, - .prefix = TMPL_ATTR_REF_PREFIX_AUTO, + .attr = { + .dict_def = request->dict, + .prefix = TMPL_ATTR_REF_PREFIX_AUTO + } }; value = fr_ldap_berval_to_string(request, values[i]); diff --git a/src/lib/redis/redis.c b/src/lib/redis/redis.c index 166b11bfe3..b352fc20e3 100644 --- a/src/lib/redis/redis.c +++ b/src/lib/redis/redis.c @@ -384,7 +384,7 @@ int fr_redis_reply_to_map(TALLOC_CTX *ctx, map_list_t *out, request_t *request, MEM(map = talloc_zero(ctx, map_t)); slen = tmpl_afrom_attr_str(map, NULL, &map->lhs, key->str, - &(tmpl_rules_t){ + &(tmpl_attr_rules_t){ .prefix = TMPL_ATTR_REF_PREFIX_NO, .dict_def = request->dict }); diff --git a/src/lib/server/cf_file.c b/src/lib/server/cf_file.c index 7335f79555..904c08eb42 100644 --- a/src/lib/server/cf_file.c +++ b/src/lib/server/cf_file.c @@ -141,16 +141,16 @@ typedef struct { static inline CC_HINT(always_inline) int cf_tmpl_rules_verify(CONF_SECTION *cs, tmpl_rules_t const *rules) { if (cf_section_has_parent(cs, "policy", NULL)) { - if (!fr_cond_assert_msg(!rules->dict_def || (rules->dict_def == fr_dict_internal()), + if (!fr_cond_assert_msg(!rules->attr.dict_def || (rules->attr.dict_def == fr_dict_internal()), "Protocol dictionary must be NULL not %s", - fr_dict_root(rules->dict_def)->name)) return -1; + fr_dict_root(rules->attr.dict_def)->name)) return -1; } else { - if (!fr_cond_assert_msg(rules->dict_def, "No protocol dictionary set")) return -1; - if (!fr_cond_assert_msg(rules->dict_def != fr_dict_internal(), "rules->dict_def must not be the internal dictionary")) return -1; + if (!fr_cond_assert_msg(rules->attr.dict_def, "No protocol dictionary set")) return -1; + if (!fr_cond_assert_msg(rules->attr.dict_def != fr_dict_internal(), "rules->attr.dict_def must not be the internal dictionary")) return -1; } - if (!fr_cond_assert_msg(!rules->allow_foreign, "rules->allow_foreign must be false")) return -1; + if (!fr_cond_assert_msg(!rules->attr.allow_foreign, "rules->allow_foreign must be false")) return -1; if (!fr_cond_assert_msg(!rules->at_runtime, "rules->at_runtime must be false")) return -1; return 0; @@ -1190,9 +1190,11 @@ static CONF_ITEM *process_if(cf_stack_t *stack) */ while (true) { tmpl_rules_t t_rules = { - .dict_def = dict, - .allow_unresolved = true, - .allow_unknown = true, + .attr = { + .dict_def = dict, + .allow_unresolved = true, + .allow_unknown = true + } }; RULES_VERIFY(cs, &t_rules); diff --git a/src/lib/server/cf_parse.c b/src/lib/server/cf_parse.c index 95af1df0b1..3012cff411 100644 --- a/src/lib/server/cf_parse.c +++ b/src/lib/server/cf_parse.c @@ -210,9 +210,11 @@ int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, UNUSED void *base, CONF_ITEM if (tmpl) { tmpl_t *vpt; static tmpl_rules_t rules = { - .allow_unknown = true, - .allow_unresolved = true, - .allow_foreign = true + .attr = { + .allow_unknown = true, + .allow_unresolved = true, + .allow_foreign = true + } }; fr_type_t cast = FR_TYPE_NULL; fr_sbuff_t sbuff = FR_SBUFF_IN(cp->value, strlen(cp->value)); @@ -1491,7 +1493,7 @@ int cf_section_parse_pass2(void *base, CONF_SECTION *cs) */ slen = xlat_tokenize(cs, &xlat, NULL, &FR_SBUFF_IN(cp->value, talloc_array_length(cp->value) - 1), NULL, - &(tmpl_rules_t){ + &(tmpl_attr_rules_t){ .dict_def = dict, .allow_unknown = false, .allow_unresolved = false, diff --git a/src/lib/server/cond_eval.c b/src/lib/server/cond_eval.c index 26027146d9..e6d9c418ee 100644 --- a/src/lib/server/cond_eval.c +++ b/src/lib/server/cond_eval.c @@ -144,7 +144,7 @@ static bool cond_eval_tmpl(request_t *request, tmpl_t const *in, fr_value_box_t /* * No cast means that it's an existence check. */ - if (fr_type_is_null(vpt->cast)) { + if (fr_type_is_null(tmpl_rules_cast(vpt))) { return (tmpl_find_vp(NULL, request, vpt) == 0); } @@ -159,10 +159,10 @@ static bool cond_eval_tmpl(request_t *request, tmpl_t const *in, fr_value_box_t MEM(box = fr_value_box_alloc_null(request)); box_free = box; - if (fr_value_box_cast(box, box, vpt->cast, NULL, &vp->data) < 0) { + if (fr_value_box_cast(box, box, tmpl_rules_cast(vpt), NULL, &vp->data) < 0) { if (request) RPEDEBUG("Failed casting %pV to type %s", box, fr_table_str_by_value(fr_value_box_type_table, - vpt->cast, "??")); + tmpl_rules_cast(vpt), "??")); goto done; } break; @@ -183,7 +183,7 @@ static bool cond_eval_tmpl(request_t *request, tmpl_t const *in, fr_value_box_t * We don't yet have xlats returning lists of * value boxes, so there's an assert. */ - if (fr_type_is_null(vpt->cast)) { + if (fr_type_is_null(tmpl_rules_cast(vpt))) { switch (box->type) { case FR_TYPE_STRING: case FR_TYPE_OCTETS: @@ -385,7 +385,7 @@ static int cond_realize_tmpl(request_t *request, * converted to the correct thing. */ case TMPL_TYPE_DATA: - fr_assert((fr_type_is_null(in->cast)) || (in->cast == tmpl_value_type(in))); + fr_assert((fr_type_is_null(tmpl_rules_cast(in))) || (tmpl_rules_cast(in) == tmpl_value_type(in))); *out = tmpl_value(in); fr_assert(!async); return 0; @@ -411,14 +411,14 @@ static int cond_realize_tmpl(request_t *request, * don't find that, then the *other* side MUST * have an explicit data type. */ - if (in->cast != FR_TYPE_NULL) { - cast_type = in->cast; + if (tmpl_rules_cast(in) != FR_TYPE_NULL) { + cast_type = tmpl_rules_cast(in); } else if (!other) { cast_type = FR_TYPE_STRING; - } else if (other->cast) { - cast_type = other->cast; + } else if (tmpl_rules_cast(other)) { + cast_type = tmpl_rules_cast(other); } else if (tmpl_is_attr(other)) { da = tmpl_da(other); @@ -484,11 +484,11 @@ static int cond_realize_attr(request_t *request, fr_value_box_t **realized, fr_v if (da) { cast_type = da->type; - } else if (vpt->cast != FR_TYPE_NULL) { + } else if (tmpl_rules_cast(vpt) != FR_TYPE_NULL) { /* * If there's an explicit cast, use that. */ - cast_type = vpt->cast; + cast_type = tmpl_rules_cast(vpt); } else { /* @@ -510,7 +510,7 @@ static int cond_realize_attr(request_t *request, fr_value_box_t **realized, fr_v if (fr_value_box_cast(request, box, cast_type, da, &vp->data) < 0) { if (request) RPEDEBUG("Failed casting %pV to type %s", &vp->data, fr_table_str_by_value(fr_value_box_type_table, - vpt->cast, "??")); + tmpl_rules_cast(vpt), "??")); return false; } @@ -527,7 +527,7 @@ static bool cond_compare_attrs(request_t *request, fr_value_box_t *lhs, map_t co fr_value_box_t *rhs, rhs_cast; fr_dict_attr_t const *da = NULL; - if (tmpl_is_attr(map->lhs) && fr_type_is_null(map->lhs->cast)) da = tmpl_da(map->lhs); + if (tmpl_is_attr(map->lhs) && fr_type_is_null(tmpl_rules_cast(map->lhs))) da = tmpl_da(map->lhs); fr_assert(lhs != NULL); rhs = NULL; /* shut up clang scan */ diff --git a/src/lib/server/cond_tokenize.c b/src/lib/server/cond_tokenize.c index a0e67d0839..ec7d462569 100644 --- a/src/lib/server/cond_tokenize.c +++ b/src/lib/server/cond_tokenize.c @@ -98,10 +98,10 @@ ssize_t cond_print(fr_sbuff_t *out, fr_cond_t const *in) break; case COND_TYPE_MAP: - if (c->data.map->lhs->cast) { + if (tmpl_rules_cast(c->data.map->lhs)) { FR_SBUFF_IN_SPRINTF_RETURN(&our_out, "<%s>", fr_table_str_by_value(fr_value_box_type_table, - c->data.map->lhs->cast, "??")); + tmpl_rules_cast(c->data.map->lhs), "??")); } FR_SBUFF_RETURN(map_print, &our_out, c->data.map); break; @@ -204,9 +204,9 @@ static int cond_cast_tmpl(tmpl_t *vpt, fr_type_t type, tmpl_t *other) * Which means we no longer need the cast. */ fr_assert(tmpl_is_data(vpt)); - fr_assert_msg(fr_type_is_null(vpt->cast) || (vpt->cast == tmpl_value_type(vpt)), + fr_assert_msg(fr_type_is_null(tmpl_rules_cast(vpt)) || (tmpl_rules_cast(vpt) == tmpl_value_type(vpt)), "Cast mismatch, target was %s, but output was %s", - fr_table_str_by_value(fr_value_box_type_table, vpt->cast, ""), + fr_table_str_by_value(fr_value_box_type_table, tmpl_rules_cast(vpt), ""), fr_table_str_by_value(fr_value_box_type_table, tmpl_value_type(vpt), "")); (void) tmpl_cast_set(vpt, FR_TYPE_NULL); return 0; @@ -228,7 +228,7 @@ int fr_cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs if (tmpl_contains_regex(c->data.map->rhs)) { fr_assert((c->data.map->op == T_OP_REG_EQ) || (c->data.map->op == T_OP_REG_NE)); fr_assert(!tmpl_is_list(c->data.map->lhs)); - fr_assert(fr_type_is_null(c->data.map->rhs->cast)); + fr_assert(fr_type_is_null(tmpl_rules_cast(c->data.map->rhs))); /* * Can't use casts with regular expressions, on @@ -242,7 +242,7 @@ int fr_cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs * @todo - ensure that the regex interpreter is * binary-safe! */ - cast_type = c->data.map->lhs->cast; + cast_type = tmpl_rules_cast(c->data.map->lhs); if (cast_type != FR_TYPE_NULL) { if ((cast_type != FR_TYPE_STRING) && (cast_type != FR_TYPE_OCTETS)) { @@ -325,8 +325,8 @@ int fr_cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs /* * Figure out the type of the LHS. */ - if (c->data.map->lhs->cast != FR_TYPE_NULL) { - lhs_type = c->data.map->lhs->cast; + if (tmpl_rules_cast(c->data.map->lhs) != FR_TYPE_NULL) { + lhs_type = tmpl_rules_cast(c->data.map->lhs); /* * Two explicit casts MUST be the same, otherwise * it's an error. @@ -334,8 +334,8 @@ int fr_cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs * We only do type promotion when at least one * data type is implicitly specified. */ - if (c->data.map->rhs->cast != FR_TYPE_NULL) { - if (c->data.map->rhs->cast != lhs_type) { + if (tmpl_rules_cast(c->data.map->rhs) != FR_TYPE_NULL) { + if (tmpl_rules_cast(c->data.map->rhs) != lhs_type) { fr_strerror_const("Incompatible casts"); if (in) fr_sbuff_set(in, fr_sbuff_start(in)); return -1; @@ -377,8 +377,8 @@ int fr_cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs /* * Figure out the type of the RHS. */ - if (c->data.map->rhs->cast != FR_TYPE_NULL) { - rhs_type = c->data.map->rhs->cast; + if (tmpl_rules_cast(c->data.map->rhs) != FR_TYPE_NULL) { + rhs_type = tmpl_rules_cast(c->data.map->rhs); } else if (tmpl_is_data(c->data.map->rhs)) { rhs_type = tmpl_value_type(c->data.map->rhs); @@ -1252,7 +1252,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out, } unary: - if (lhs->cast != FR_TYPE_NULL) { + if (tmpl_rules_cast(lhs) != FR_TYPE_NULL) { fr_strerror_const("Cannot do cast for existence check"); fr_sbuff_set(&our_in, &m_lhs_cast); goto error; diff --git a/src/lib/server/map.c b/src/lib/server/map.c index fe0a9e5363..1f1a04c6c1 100644 --- a/src/lib/server/map.c +++ b/src/lib/server/map.c @@ -97,7 +97,7 @@ static inline map_t *map_alloc(TALLOC_CTX *ctx, map_t *parent) int map_afrom_cp(TALLOC_CTX *ctx, map_t **out, map_t *parent, CONF_PAIR *cp, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules) { - map_t *map; + map_t *map; char const *attr, *value, *marker_subject; ssize_t slen; fr_token_t type; @@ -146,7 +146,7 @@ int map_afrom_cp(TALLOC_CTX *ctx, map_t **out, map_t *parent, CONF_PAIR *cp, break; default: - slen = tmpl_afrom_attr_str(ctx, NULL, &map->lhs, attr, lhs_rules); + slen = tmpl_afrom_attr_str(ctx, NULL, &map->lhs, attr, &lhs_rules->attr); if (slen <= 0) { cf_log_err(cp, "Failed parsing attribute reference %s - %s", attr, fr_strerror()); marker_subject = attr; @@ -321,14 +321,14 @@ ssize_t map_afrom_substr(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, fr_sbuf tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, fr_sbuff_parse_rules_t const *p_rules) { - ssize_t slen; - fr_token_t token; - map_t *map; - bool is_child; - fr_sbuff_t our_in = FR_SBUFF(in); - fr_sbuff_marker_t m_lhs, m_rhs, m_op; - fr_sbuff_term_t const *tt = p_rules ? p_rules->terminals : NULL; - map_t *parent, *new_parent; + ssize_t slen; + fr_token_t token; + map_t *map; + bool is_child; + fr_sbuff_t our_in = FR_SBUFF(in); + fr_sbuff_marker_t m_lhs, m_rhs, m_op; + fr_sbuff_term_t const *tt = p_rules ? p_rules->terminals : NULL; + map_t *parent, *new_parent; if (parent_p) { new_parent = parent = *parent_p; @@ -355,14 +355,20 @@ ssize_t map_afrom_substr(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, fr_sbuf break; default: + { + tmpl_attr_rules_t our_lhs_attr_rules; + + if (lhs_rules) { + our_lhs_attr_rules = lhs_rules->attr; + } else { + memset(&our_lhs_attr_rules, 0, sizeof(our_lhs_attr_rules)); + } /* * Allow for ".foo" to refer to the current * parents list. Allow for "..foo" to refer to * the grandparent list. */ - if (lhs_rules->prefix == TMPL_ATTR_REF_PREFIX_NO) { - tmpl_rules_t our_lhs_rules; - + if (lhs_rules->attr.prefix == TMPL_ATTR_REF_PREFIX_NO) { /* * One '.' means "the current parent". */ @@ -393,12 +399,11 @@ ssize_t map_afrom_substr(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, fr_sbuf * Start looking in the correct parent, not in whatever we were handed. */ if (is_child) { - our_lhs_rules = *lhs_rules; fr_assert(tmpl_is_attr(parent->lhs)); - our_lhs_rules.attr_parent = tmpl_da(parent->lhs); + our_lhs_attr_rules.parent = tmpl_da(parent->lhs); slen = tmpl_afrom_attr_substr(map, NULL, &map->lhs, &our_in, - &map_parse_rules_bareword_quoted, &our_lhs_rules); + &map_parse_rules_bareword_quoted, &our_lhs_attr_rules); break; } @@ -411,9 +416,10 @@ ssize_t map_afrom_substr(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, fr_sbuf } slen = tmpl_afrom_attr_substr(map, NULL, &map->lhs, &our_in, - &map_parse_rules_bareword_quoted, lhs_rules); + &map_parse_rules_bareword_quoted, &our_lhs_attr_rules); break; } + } if (!map->lhs) { error: @@ -635,37 +641,6 @@ check_for_child: return fr_sbuff_set(in, &our_in); } - -static int _map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, map_t *parent, CONF_SECTION *cs, - tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, - map_validate_t validate, void *uctx, - unsigned int max); - - -/** Convert an 'update' config section into an attribute map. - * - * Uses 'name2' of section to set default request and lists. - * - * @param[in] ctx for talloc. - * @param[out] out Where to store the allocated map. - * @param[in] cs the update section - * @param[in] lhs_rules rules for parsing LHS attribute references. - * @param[in] rhs_rules rules for parsing RHS attribute references. - * @param[in] validate map using this callback (may be NULL). - * @param[in] uctx to pass to callback. - * @param[in] max number of mappings to process. - * @return - * - 0 on success. - * - -1 on failure. - */ -int map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, CONF_SECTION *cs, - tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, - map_validate_t validate, void *uctx, - unsigned int max) -{ - return _map_afrom_cs(ctx, out, NULL, cs, lhs_rules, rhs_rules, validate, uctx, max); -} - static int _map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, map_t *parent, CONF_SECTION *cs, tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, map_validate_t validate, void *uctx, @@ -695,14 +670,14 @@ static int _map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, map_t *parent, CONF_S */ cs_list = p = cf_section_name2(cs); if (cs_list && (strcmp(cf_section_name1(cs), "update") == 0)) { - p += tmpl_request_ref_by_name(&our_lhs_rules.request_def, p, REQUEST_CURRENT); - if (our_lhs_rules.request_def == REQUEST_UNKNOWN) { + p += tmpl_request_ref_by_name(&our_lhs_rules.attr.request_def, p, REQUEST_CURRENT); + if (our_lhs_rules.attr.request_def == REQUEST_UNKNOWN) { cf_log_err(ci, "Default request specified in mapping section is invalid"); return -1; } - our_lhs_rules.list_def = fr_table_value_by_str(pair_list_table, p, PAIR_LIST_UNKNOWN); - if (our_lhs_rules.list_def == PAIR_LIST_UNKNOWN) { + our_lhs_rules.attr.list_def = fr_table_value_by_str(pair_list_table, p, PAIR_LIST_UNKNOWN); + if (our_lhs_rules.attr.list_def == PAIR_LIST_UNKNOWN) { cf_log_err(ci, "Default list \"%s\" specified in mapping section is invalid", p); return -1; } @@ -727,11 +702,11 @@ static int _map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, map_t *parent, CONF_S * assignment operator, THEN we allow sub-maps. */ if (cf_item_is_section(ci)) { - CONF_SECTION *subcs; - fr_token_t token; - ssize_t slen; - bool qualifiers = our_lhs_rules.disallow_qualifiers; - map_list_t child_list; + CONF_SECTION *subcs; + fr_token_t token; + ssize_t slen; + bool qualifiers = our_lhs_rules.attr.disallow_qualifiers; + map_list_t child_list; map_list_init(&child_list); subcs = cf_item_to_section(ci); @@ -753,7 +728,7 @@ static int _map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, map_t *parent, CONF_S * them for now. Once the functionality * is tested and used, we can allow that. */ - slen = tmpl_afrom_attr_str(ctx, NULL, &map->lhs, cf_section_name1(subcs), &our_lhs_rules); + slen = tmpl_afrom_attr_str(ctx, NULL, &map->lhs, cf_section_name1(subcs), &our_lhs_rules.attr); if (slen <= 0) { cf_log_err(ci, "Failed parsing attribute reference for list %s - %s", cf_section_name1(subcs), fr_strerror()); @@ -784,15 +759,15 @@ static int _map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, map_t *parent, CONF_S * the child attributes go into the * parent one. */ - our_lhs_rules.disallow_qualifiers = true; + our_lhs_rules.attr.disallow_qualifiers = true; /* * The leaf reference of the outer section * is used as the parsing context of the * inner section. */ - our_lhs_rules.attr_parent = tmpl_da(map->lhs); - our_lhs_rules.prefix = TMPL_ATTR_REF_PREFIX_NO; + our_lhs_rules.attr.parent = tmpl_da(map->lhs); + our_lhs_rules.attr.prefix = TMPL_ATTR_REF_PREFIX_NO; /* * This prints out any relevant error @@ -812,7 +787,7 @@ static int _map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, map_t *parent, CONF_S } map_list_move(&map->child, &child_list); - our_lhs_rules.disallow_qualifiers = qualifiers; + our_lhs_rules.attr.disallow_qualifiers = qualifiers; MAP_VERIFY(map); goto next; } @@ -847,6 +822,30 @@ static int _map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, map_t *parent, CONF_S } +/** Convert an 'update' config section into an attribute map. + * + * Uses 'name2' of section to set default request and lists. + * + * @param[in] ctx for talloc. + * @param[out] out Where to store the allocated map. + * @param[in] cs the update section + * @param[in] lhs_rules rules for parsing LHS attribute references. + * @param[in] rhs_rules rules for parsing RHS attribute references. + * @param[in] validate map using this callback (may be NULL). + * @param[in] uctx to pass to callback. + * @param[in] max number of mappings to process. + * @return + * - 0 on success. + * - -1 on failure. + */ +int map_afrom_cs(TALLOC_CTX *ctx, map_list_t *out, CONF_SECTION *cs, + tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules, + map_validate_t validate, void *uctx, + unsigned int max) +{ + return _map_afrom_cs(ctx, out, NULL, cs, lhs_rules, rhs_rules, validate, uctx, max); +} + /** Convert a value box to a map * * This is mainly used in IO modules, where another function is used to convert @@ -969,8 +968,8 @@ int map_afrom_vp(TALLOC_CTX *ctx, map_t **out, fr_pair_t *vp, tmpl_rules_t const tmpl_attr_set_leaf_da(map->lhs, vp->da); tmpl_attr_set_leaf_num(map->lhs, NUM_ANY); - tmpl_attr_set_request(map->lhs, rules->request_def); - tmpl_attr_set_list(map->lhs, rules->list_def); + tmpl_attr_set_request(map->lhs, rules->attr.request_def); + tmpl_attr_set_list(map->lhs, rules->attr.list_def); tmpl_print(&FR_SBUFF_OUT(buffer, sizeof(buffer)), map->lhs, TMPL_ATTR_REF_PREFIX_YES, NULL); tmpl_set_name(map->lhs, T_BARE_WORD, buffer, -1); @@ -1448,9 +1447,9 @@ int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t f } slen = tmpl_afrom_attr_str(tmp_ctx, NULL, &exp_lhs, attr_str, - &(tmpl_rules_t){ - .dict_def = request->dict, - .prefix = TMPL_ATTR_REF_PREFIX_NO + &(tmpl_attr_rules_t){ + .dict_def = request->dict, + .prefix = TMPL_ATTR_REF_PREFIX_NO }); if (slen <= 0) { RPEDEBUG("Left side expansion result \"%s\" is not an attribute reference", attr_str); diff --git a/src/lib/server/map_async.c b/src/lib/server/map_async.c index 25a66536e9..2d32b9fac7 100644 --- a/src/lib/server/map_async.c +++ b/src/lib/server/map_async.c @@ -329,9 +329,9 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, } slen = tmpl_afrom_attr_str(tmp_ctx, NULL, &map_tmp.lhs, lhs_result_head->vb_strvalue, - &(tmpl_rules_t){ - .dict_def = request->dict, - .prefix = TMPL_ATTR_REF_PREFIX_NO + &(tmpl_attr_rules_t){ + .dict_def = request->dict, + .prefix = TMPL_ATTR_REF_PREFIX_NO }); if (slen <= 0) { RPEDEBUG("Left side expansion result \"%s\" is not an attribute reference", @@ -727,11 +727,12 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, (void)fr_pair_dcursor_init(&from, &vp_head); while ((vp = fr_dcursor_remove(&from))) { map_t *mod; - tmpl_rules_t rules; - - memset(&rules, 0, sizeof(rules)); - rules.request_def = tmpl_request(mutated->lhs); - rules.list_def = tmpl_list(mutated->lhs); + tmpl_rules_t rules = { + .attr = { + .request_def = tmpl_request(mutated->lhs), + .list_def = tmpl_list(mutated->lhs) + } + }; if (map_afrom_vp(n, &mod, vp, &rules) < 0) { RPEDEBUG("Failed converting VP to map"); diff --git a/src/lib/server/tmpl.h b/src/lib/server/tmpl.h index 8559d3ee95..4b278a9c81 100644 --- a/src/lib/server/tmpl.h +++ b/src/lib/server/tmpl.h @@ -249,6 +249,9 @@ extern fr_table_num_ordered_t const tmpl_type_table[]; extern size_t tmpl_type_table_len; typedef struct tmpl_rules_s tmpl_rules_t; +typedef struct tmpl_attr_rules_s tmpl_attr_rules_t; +typedef struct tmpl_data_rules_s tmpl_data_rules_t; +typedef struct tmpl_xlat_rules_s tmpl_xlat_rules_t; typedef struct tmpl_res_rules_s tmpl_res_rules_t; typedef struct tmpl_s tmpl_t; @@ -278,12 +281,7 @@ typedef enum { TMPL_ATTR_REF_PREFIX_AUTO //!< Attribute refs may have a '&' prefix. } tmpl_attr_prefix_t; -/** Optional arguments passed to vp_tmpl functions - * - */ -struct tmpl_rules_s { - tmpl_rules_t const *parent; //!< for parent / child relationships - +struct tmpl_attr_rules_s { fr_dict_t const *dict_def; //!< Default dictionary to use ///< with unqualified attribute references. @@ -293,7 +291,7 @@ struct tmpl_rules_s { tmpl_pair_list_t list_def; //!< Default list to use with unqualified ///< attribute reference. - fr_dict_attr_t const *attr_parent; //!< Point in dictionary tree to resume parsing + fr_dict_attr_t const *parent; //!< Point in dictionary tree to resume parsing ///< from. If this is provided then dict_def ///< request_def and list_def will be ignored ///< and the presence of any of those qualifiers @@ -315,17 +313,38 @@ struct tmpl_rules_s { bool disallow_filters; //!< disallow filters. - bool at_runtime; //!< Produce an ephemeral/runtime tmpl. - ///< Instantiated xlats are not added to the global - ///< trees, regexes are not JIT'd. bool list_as_attr; //!< return #TMPL_TYPE_ATTR for lists, and not #TMPL_TYPE_LIST + tmpl_attr_prefix_t prefix; //!< Whether the attribute reference requires + ///< a prefix. +}; + +struct tmpl_data_rules_s { + fr_dict_attr_t const *enumv; //!< Enumeration attribute used to resolve enum values. + + fr_type_t cast; //!< Whether there was an explicit cast. + ///< Used to determine if barewords or other values + ///< should be converted to an internal data type. +}; +struct tmpl_xlat_rules_s { fr_event_list_t *runtime_el; //!< The eventlist to use for runtime instantiation ///< of xlats. +}; - tmpl_attr_prefix_t prefix; //!< Whether the attribute reference requires - ///< a prefix. +/** Optional arguments passed to vp_tmpl functions + * + */ +struct tmpl_rules_s { + tmpl_rules_t const *parent; //!< for parent / child relationships + + tmpl_attr_rules_t attr; //!< Rules/data for parsing attribute references. + tmpl_data_rules_t data; //!< Rules/data for parsing attribute data and enumerations. + tmpl_xlat_rules_t xlat; //!< Rules/data for parsing xlats. + + bool at_runtime; //!< Produce an ephemeral/runtime tmpl. + ///< Instantiated xlats are not added to the global + ///< trees, regexes are not JIT'd. }; /** Similar to tmpl_rules_t, but used to specify parameters that may change during subsequent resolution passes @@ -542,10 +561,6 @@ struct tmpl_s { }; } data; - fr_type_t _CONST cast; //!< Type we should interpret unresolved data with. - fr_dict_attr_t const * _CONST enumv; //!< Enumeration we should use when parsing unescaped - ///< i.e. barewords with an unknown format. - tmpl_rules_t _CONST rules; //!< The rules that were used when creating the tmpl. ///< These are useful for multiple resolution passes as ///< they ensure the correct parsing rules are applied. @@ -676,6 +691,9 @@ static inline tmpl_pair_list_t tmpl_list(tmpl_t const *vpt) #define tmpl_value_type(_tmpl) (_tmpl)->data.literal.type #define tmpl_value_enumv(_tmpl) (_tmpl)->data.literal.enumv +#define tmpl_rules_cast(_tmpl) (_tmpl)->rules.data.cast +#define tmpl_rules_enumv(_tmpl) (_tmpl)->rules.data.enumv + /* * Temporary macros to track where we do assignments */ @@ -907,11 +925,11 @@ int tmpl_attr_afrom_list(TALLOC_CTX *ctx, tmpl_t **out, tmpl_t const *list, ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t **out, fr_sbuff_t *name, fr_sbuff_parse_rules_t const *p_rules, - tmpl_rules_t const *t_rules); + tmpl_attr_rules_t const *t_rules); ssize_t tmpl_afrom_attr_str(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t **out, char const *name, - tmpl_rules_t const *rules) CC_HINT(nonnull (3, 4)); + tmpl_attr_rules_t const *rules) CC_HINT(nonnull (3, 4)); ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, diff --git a/src/lib/server/tmpl_dcursor.c b/src/lib/server/tmpl_dcursor.c index ca816db3e1..fd3cba5840 100644 --- a/src/lib/server/tmpl_dcursor.c +++ b/src/lib/server/tmpl_dcursor.c @@ -367,7 +367,7 @@ fr_pair_t *tmpl_dcursor_init(int *err, TALLOC_CTX *ctx, tmpl_dcursor_ctx_t *cc, /* * Get the right list in the specified context */ - if (!vpt->rules.list_as_attr) { + if (!vpt->rules.attr.list_as_attr) { list_head = tmpl_list_head(request, tmpl_list(vpt)); if (!list_head) { fr_strerror_printf("List \"%s\" not available in this context", @@ -513,7 +513,7 @@ int tmpl_extents_find(TALLOC_CTX *ctx, } } - if (!vpt->rules.list_as_attr) { + if (!vpt->rules.attr.list_as_attr) { /* * Get the right list in the specified context */ diff --git a/src/lib/server/tmpl_eval.c b/src/lib/server/tmpl_eval.c index c294637a7e..adaef27f3d 100644 --- a/src/lib/server/tmpl_eval.c +++ b/src/lib/server/tmpl_eval.c @@ -252,7 +252,7 @@ fr_type_t tmpl_expanded_type(tmpl_t const *vpt) /* * Casts take precedence over everything. */ - if (vpt->cast != FR_TYPE_NULL) return vpt->cast; + if (tmpl_rules_cast(vpt) != FR_TYPE_NULL) return tmpl_rules_cast(vpt); /* * Anything that's not a bare word will diff --git a/src/lib/server/tmpl_tokenize.c b/src/lib/server/tmpl_tokenize.c index 7fdc292a2e..92d3edd269 100644 --- a/src/lib/server/tmpl_tokenize.c +++ b/src/lib/server/tmpl_tokenize.c @@ -48,8 +48,10 @@ RCSID("$Id$") * Defaults are used if a NULL rules pointer is passed to the parsing function. */ static tmpl_rules_t const default_attr_rules = { - .request_def = REQUEST_CURRENT, - .list_def = PAIR_LIST_REQUEST + .attr = { + .request_def = REQUEST_CURRENT, + .list_def = PAIR_LIST_REQUEST + } }; /* clang-format off */ @@ -555,7 +557,7 @@ void tmpl_set_name(tmpl_t *vpt, fr_token_t quote, char const *name, ssize_t len) */ void tmpl_set_dict_def(tmpl_t *vpt, fr_dict_t const *dict) { - vpt->rules.dict_def = dict; + vpt->rules.attr.dict_def = dict; } /** Initialise a tmpl using a format string to create the name @@ -1097,7 +1099,7 @@ static inline CC_HINT(always_inline) void tmpl_attr_insert(tmpl_t *vpt, tmpl_att * - TMPL_ATTR_REF_BAD_FILTER on failure. */ static tmpl_attr_filter_t tmpl_attr_parse_filter(tmpl_attr_error_t *err, tmpl_attr_t *ar, - fr_sbuff_t *name, tmpl_rules_t const *t_rules) + fr_sbuff_t *name, tmpl_attr_rules_t const *t_rules) { /* * Parse array subscript (and eventually complex filters) @@ -1191,7 +1193,7 @@ static inline CC_HINT(nonnull(3,6)) int tmpl_attr_afrom_attr_unresolved_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t *vpt, fr_dict_attr_t const *parent, fr_dict_attr_t const *namespace, - fr_sbuff_t *name, tmpl_rules_t const *t_rules, + fr_sbuff_t *name, tmpl_attr_rules_t const *t_rules, unsigned int depth) { tmpl_attr_t *ar = NULL; @@ -1306,7 +1308,7 @@ static inline int tmpl_attr_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t tmpl_t *vpt, fr_dict_attr_t const *parent, fr_dict_attr_t const *namespace, fr_sbuff_t *name, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, + fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules, unsigned int depth) { uint32_t oid = 0; @@ -1371,7 +1373,7 @@ static inline int tmpl_attr_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t * Discard any errors here... It's more * useful to have the original. */ - if (!da && !vpt->rules.disallow_internal && + if (!da && !vpt->rules.attr.disallow_internal && (ar = tmpl_attr_list_tail(&vpt->data.attribute.ar)) && (ar->type == TMPL_ATTR_TYPE_NORMAL) && (ar->ar_da->type == FR_TYPE_GROUP)) { (void)fr_dict_attr_by_name_substr(NULL, @@ -1690,7 +1692,7 @@ static inline int tmpl_request_ref_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_ tmpl_t *vpt, fr_sbuff_t *name, fr_sbuff_parse_rules_t const *p_rules, - tmpl_rules_t const **pt_rules, + tmpl_attr_rules_t const **pt_rules, unsigned int depth) { tmpl_request_ref_t ref; @@ -1698,7 +1700,7 @@ static inline int tmpl_request_ref_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_ tmpl_request_t *rr; FR_DLIST_HEAD(tmpl_request_list) *list = &vpt->data.attribute.rr; fr_sbuff_marker_t s_m; - tmpl_rules_t const *t_rules = *pt_rules; + tmpl_attr_rules_t const *t_rules = *pt_rules; fr_sbuff_marker(&s_m, name); fr_sbuff_out_by_longest_prefix(&ref_len, &ref, tmpl_request_ref_table, name, t_rules->request_def); @@ -1745,7 +1747,7 @@ static inline int tmpl_request_ref_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_ return -1; } - if (t_rules->attr_parent || t_rules->disallow_qualifiers) { + if (t_rules->parent || t_rules->disallow_qualifiers) { fr_strerror_const("It is not permitted to specify a request reference here"); if (err) *err = TMPL_ATTR_ERROR_INVALID_LIST_QUALIFIER; return -1; @@ -1760,14 +1762,6 @@ static inline int tmpl_request_ref_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_ }; tmpl_request_list_insert_tail(list, rr); - /* - * Update the parsing rules if we go to the parent. - */ - if (((ref == REQUEST_OUTER) || (ref == REQUEST_PARENT)) && t_rules->parent) { - t_rules = t_rules->parent; - *pt_rules = t_rules; - } - /* * Advance past the separator (if there is one) */ @@ -1829,7 +1823,7 @@ static inline int tmpl_request_ref_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, tmpl_t **out, fr_sbuff_t *name, fr_sbuff_parse_rules_t const *p_rules, - tmpl_rules_t const *t_rules) + tmpl_attr_rules_t const *t_rules) { int ret; size_t list_len = 0; @@ -1839,7 +1833,7 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, bool is_raw = false; fr_sbuff_marker_t m_l; - if (!t_rules) t_rules = &default_attr_rules; /* Use the defaults */ + if (!t_rules) t_rules = &default_attr_rules.attr; /* Use the defaults */ if (err) *err = TMPL_ATTR_ERROR_NONE; @@ -1925,7 +1919,7 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, vpt->data.attribute.list = t_rules->list_def; } - if ((t_rules->attr_parent || t_rules->disallow_qualifiers) && (list_len > 0)) { + if ((t_rules->parent || t_rules->disallow_qualifiers) && (list_len > 0)) { fr_strerror_const("It is not permitted to specify a pair list here"); if (err) *err = TMPL_ATTR_ERROR_INVALID_LIST_QUALIFIER; talloc_free(vpt); @@ -1944,7 +1938,7 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, (fr_sbuff_next_if_char(&our_name, '.') && fr_sbuff_is_in_charset(&our_name, fr_dict_attr_allowed_chars))) { ret = tmpl_attr_afrom_attr_substr(vpt, err, vpt, - t_rules->attr_parent, t_rules->attr_parent, + t_rules->parent, t_rules->parent, &our_name, p_rules, t_rules, 0); if (ret < 0) goto error; @@ -2037,7 +2031,7 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, } tmpl_set_name(vpt, T_BARE_WORD, fr_sbuff_start(&our_name), fr_sbuff_used(&our_name)); - vpt->rules = *t_rules; /* Record the rules */ + vpt->rules.attr = *t_rules; /* Record the rules */ if (!tmpl_substr_terminal_check(&our_name, p_rules)) { fr_strerror_const("Unexpected text after attribute reference"); @@ -2068,11 +2062,11 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err, * name string isn't parsed. */ ssize_t tmpl_afrom_attr_str(TALLOC_CTX *ctx, tmpl_attr_error_t *err, - tmpl_t **out, char const *name, tmpl_rules_t const *t_rules) + tmpl_t **out, char const *name, tmpl_attr_rules_t const *t_rules) { ssize_t slen, name_len; - if (!t_rules) t_rules = &default_attr_rules; /* Use the defaults */ + if (!t_rules) t_rules = &default_attr_rules.attr; /* Use the defaults */ name_len = strlen(name); slen = tmpl_afrom_attr_substr(ctx, err, out, &FR_SBUFF_IN(name, name_len), NULL, t_rules); @@ -2578,7 +2572,7 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, * we find a '&' prefix. */ if (fr_sbuff_is_char(&our_in, '&')) return tmpl_afrom_attr_substr(ctx, NULL, out, in, - p_rules, t_rules); + p_rules, &t_rules->attr); /* * Allow bareword xlats if we @@ -2591,10 +2585,11 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, vpt = tmpl_alloc_null(ctx); if (!t_rules->at_runtime) { - slen = xlat_tokenize(vpt, &head, &flags, &our_in, p_rules, t_rules); + slen = xlat_tokenize(vpt, &head, &flags, &our_in, p_rules, &t_rules->attr); } else { slen = xlat_tokenize_ephemeral(vpt, &head, - t_rules->runtime_el, &flags, &our_in, p_rules, t_rules); + t_rules->xlat.runtime_el, &flags, &our_in, + p_rules, t_rules); } if (!head) return slen; @@ -2674,7 +2669,7 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, * See if it's an attribute reference * without the prefix. */ - slen = tmpl_afrom_attr_substr(ctx, NULL, out, &our_in, p_rules, t_rules); + slen = tmpl_afrom_attr_substr(ctx, NULL, out, &our_in, p_rules, &t_rules->attr); if (slen > 0) goto done_bareword; fr_assert(!*out); @@ -2717,9 +2712,9 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, vpt = tmpl_alloc_null(ctx); if (!t_rules->at_runtime) { - slen = xlat_tokenize(vpt, &head, &flags, &our_in, p_rules, t_rules); + slen = xlat_tokenize(vpt, &head, &flags, &our_in, p_rules, &t_rules->attr); } else { - slen = xlat_tokenize_ephemeral(vpt, &head, t_rules->runtime_el, + slen = xlat_tokenize_ephemeral(vpt, &head, t_rules->xlat.runtime_el, &flags, &our_in, p_rules, t_rules); } if (!head) return slen; @@ -2765,7 +2760,7 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, * FIXME - We need an ephemeral version of this * too. */ - slen = xlat_tokenize_argv(vpt, &head, &flags, &our_in, p_rules, t_rules); + slen = xlat_tokenize_argv(vpt, &head, &flags, &our_in, p_rules, &t_rules->attr); if (slen < 0) { fr_sbuff_advance(&our_in, slen * -1); talloc_free(vpt); @@ -2788,7 +2783,7 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, vpt = tmpl_alloc_null(ctx); - slen = xlat_tokenize(vpt, &head, &flags, &our_in, p_rules, t_rules); + slen = xlat_tokenize(vpt, &head, &flags, &our_in, p_rules, &t_rules->attr); if (!head) return slen; /* @@ -2801,7 +2796,6 @@ ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, * The caller will need to do the compilation * after we return. */ - if (xlat_to_string(vpt, &str, &head)) { tmpl_init(vpt, TMPL_TYPE_REGEX_UNCOMPILED, quote, fr_sbuff_start(&our_in), slen); vpt->data.unescaped = str; /* Store the unescaped string for compilation later */ @@ -2850,8 +2844,6 @@ tmpl_t *tmpl_copy(TALLOC_CTX *ctx, tmpl_t const *in) tmpl_t *vpt; MEM(vpt = tmpl_alloc(ctx, in->type, in->quote, in->name, in->len)); - vpt->cast = in->cast; - vpt->enumv = in->enumv; vpt->rules = in->rules; /* @@ -3011,7 +3003,7 @@ int tmpl_cast_set(tmpl_t *vpt, fr_type_t dst_type) */ check_types: if (src_type == dst_type) { - vpt->cast = FR_TYPE_NULL; + tmpl_rules_cast(vpt) = FR_TYPE_NULL; return 0; } @@ -3025,7 +3017,7 @@ int tmpl_cast_set(tmpl_t *vpt, fr_type_t dst_type) } done: - vpt->cast = dst_type; + vpt->rules.data.cast = dst_type; return 0; } @@ -3188,7 +3180,7 @@ int tmpl_cast_in_place(tmpl_t *vpt, fr_type_t type, fr_dict_attr_t const *enumv) case TMPL_TYPE_ATTR: /* FIXME - We should check cast compatibility with resolved attrs */ case TMPL_TYPE_ATTR_UNRESOLVED: - vpt->cast = type; + vpt->rules.data.cast = type; break; default: @@ -3222,7 +3214,7 @@ static inline CC_HINT(always_inline) int tmpl_attr_resolve(tmpl_t *vpt, tmpl_res TMPL_VERIFY(vpt); - dict_def = vpt->rules.dict_def; + dict_def = vpt->rules.attr.dict_def; if (!tr_rules->dict_def || tr_rules->force_dict_def) dict_def = tr_rules->dict_def; /* @@ -3240,8 +3232,8 @@ static inline CC_HINT(always_inline) int tmpl_attr_resolve(tmpl_t *vpt, tmpl_res &FR_SBUFF_IN(ar->ar_unresolved, talloc_array_length(ar->ar_unresolved) - 1), NULL, - !vpt->rules.disallow_internal, - vpt->rules.allow_foreign); + !vpt->rules.attr.disallow_internal, + vpt->rules.attr.allow_foreign); if (!da) return -2; /* Can't resolve, maybe the caller can resolve later */ ar->ar_type = TMPL_ATTR_TYPE_NORMAL; @@ -3252,7 +3244,7 @@ static inline CC_HINT(always_inline) int tmpl_attr_resolve(tmpl_t *vpt, tmpl_res * Record the dictionary that was * successfully used for resolution. */ - vpt->rules.dict_def = tr_rules->dict_def; + vpt->rules.attr.dict_def = tr_rules->dict_def; /* * Reach into the next reference @@ -3298,7 +3290,7 @@ static inline CC_HINT(always_inline) int tmpl_attr_resolve(tmpl_t *vpt, tmpl_res */ if (!da) { prev = tmpl_attr_list_prev(&vpt->data.attribute.ar, ar); - if (!vpt->rules.disallow_internal && prev && (prev->ar_da->type == FR_TYPE_GROUP)) { + if (!vpt->rules.attr.disallow_internal && prev && (prev->ar_da->type == FR_TYPE_GROUP)) { (void)fr_dict_attr_by_name_substr(NULL, &da, fr_dict_root(fr_dict_internal()), @@ -3392,7 +3384,7 @@ int tmpl_xlat_resolve(tmpl_t *vpt, tmpl_res_rules_t const *tr_rules) /** Attempt to resolve functions and attributes in xlats and attribute references * - * @note If resolution is successful, the rules->dict_def field will be modified to + * @note If resolution is successful, the rules->attr.dict_def field will be modified to * reflect the dictionary resolution was successful in. * * @param[in,out] vpt to resolve. Should be of type TMPL_TYPE_XLAT_UNRESOLVED @@ -3429,7 +3421,7 @@ int tmpl_resolve(tmpl_t *vpt, tmpl_res_rules_t const *tr_rules) * Convert unresolved tmpls into literal string values. */ } else if (tmpl_is_unresolved(vpt)) { - fr_type_t dst_type = vpt->cast; + fr_type_t dst_type = tmpl_rules_cast(vpt); if (fr_type_is_null(dst_type)) dst_type = FR_TYPE_STRING; /* Default to strings */ diff --git a/src/lib/server/users_file.c b/src/lib/server/users_file.c index a0e2a7b001..30086d82e3 100644 --- a/src/lib/server/users_file.c +++ b/src/lib/server/users_file.c @@ -269,25 +269,29 @@ int pairlist_read(TALLOC_CTX *ctx, fr_dict_t const *dict, char const *file, PAIR relative_map = NULL; lhs_rules = (tmpl_rules_t) { - .dict_def = dict, - .request_def = REQUEST_CURRENT, - .prefix = TMPL_ATTR_REF_PREFIX_NO, - .disallow_qualifiers = true, /* for now, until more tests are made */ + .attr = { + .dict_def = dict, + .request_def = REQUEST_CURRENT, + .prefix = TMPL_ATTR_REF_PREFIX_NO, + .disallow_qualifiers = true, /* for now, until more tests are made */ - /* - * Otherwise the tmpl code returns 0 when asked - * to parse unknown names. So we say "please - * parse unknown names as unresolved attributes", - * and then do a second pass to complain that the - * thing isn't known. - */ - .allow_unresolved = true, + /* + * Otherwise the tmpl code returns 0 when asked + * to parse unknown names. So we say "please + * parse unknown names as unresolved attributes", + * and then do a second pass to complain that the + * thing isn't known. + */ + .allow_unresolved = true + } }; rhs_rules = (tmpl_rules_t) { - .dict_def = dict, - .request_def = REQUEST_CURRENT, - .prefix = TMPL_ATTR_REF_PREFIX_YES, - .disallow_qualifiers = true, /* for now, until rlm_files supports it */ + .attr = { + .dict_def = dict, + .request_def = REQUEST_CURRENT, + .prefix = TMPL_ATTR_REF_PREFIX_YES, + .disallow_qualifiers = true, /* for now, until rlm_files supports it */ + } }; while (true) { @@ -381,7 +385,7 @@ int pairlist_read(TALLOC_CTX *ctx, fr_dict_t const *dict, char const *file, PAIR } t->name = q; - lhs_rules.list_def = PAIR_LIST_CONTROL; + lhs_rules.attr.list_def = PAIR_LIST_CONTROL; comma = false; check_item: @@ -535,7 +539,7 @@ setup_reply: /* * Setup the reply items. */ - lhs_rules.list_def = PAIR_LIST_REPLY; + lhs_rules.attr.list_def = PAIR_LIST_REPLY; comma = false; reply_item: diff --git a/src/lib/server/virtual_servers.c b/src/lib/server/virtual_servers.c index 42d81d5956..856657718c 100644 --- a/src/lib/server/virtual_servers.c +++ b/src/lib/server/virtual_servers.c @@ -735,8 +735,8 @@ static int process_instantiate(CONF_SECTION *server_cs, dl_module_inst_t *dl_ins tmpl_rules_t parse_rules; memset(&parse_rules, 0, sizeof(parse_rules)); - parse_rules.dict_def = dict; - fr_assert(parse_rules.dict_def != NULL); + parse_rules.attr.dict_def = dict; + fr_assert(parse_rules.attr.dict_def != NULL); if (virtual_server_compile_sections(server_cs, process->compile_list, &parse_rules, dl_inst->data) < 0) { diff --git a/src/lib/unlang/compile.c b/src/lib/unlang/compile.c index 58b269b658..ac2231c657 100644 --- a/src/lib/unlang/compile.c +++ b/src/lib/unlang/compile.c @@ -200,16 +200,24 @@ static const unlang_actions_t default_actions[MOD_COUNT] = } }; -static inline CC_HINT(always_inline) int unlang_rules_verify(tmpl_rules_t const *rules) +static inline CC_HINT(always_inline) int unlang_attr_rules_verify(tmpl_attr_rules_t const *rules) { if (!fr_cond_assert_msg(rules->dict_def, "No protocol dictionary set")) return -1; - if (!fr_cond_assert_msg(rules->dict_def != fr_dict_internal(), "rules->dict_def must not be the internal dictionary")) return -1; - if (!fr_cond_assert_msg(!rules->allow_foreign, "rules->allow_foreign must be false")) return -1; - if (!fr_cond_assert_msg(!rules->at_runtime, "rules->at_runtime must be false")) return -1; + if (!fr_cond_assert_msg(rules->dict_def != fr_dict_internal(), "rules->attr.dict_def must not be the internal dictionary")) return -1; + if (!fr_cond_assert_msg(!rules->allow_foreign, "rules->attr.allow_foreign must be false")) return -1; return 0; } +static inline CC_HINT(always_inline) int unlang_rules_verify(tmpl_rules_t const *rules) +{ + if (!fr_cond_assert_msg(!rules->at_runtime, "rules->at_runtime must be false")) return -1; + return unlang_attr_rules_verify(&rules->attr); +} + +#if 0 +#define ATTR_RULES_VERIFY(_rules) if (unlang_attr_rules_verify(_rules) < 0) return NULL; +#endif #define RULES_VERIFY(_rules) if (unlang_rules_verify(_rules) < 0) return NULL; static bool pass2_fixup_tmpl(TALLOC_CTX *ctx, tmpl_t **vpt_p, CONF_ITEM const *ci, fr_dict_t const *dict) @@ -222,7 +230,7 @@ static bool pass2_fixup_tmpl(TALLOC_CTX *ctx, tmpl_t **vpt_p, CONF_ITEM const *c * We may now know the correct dictionary * where we didn't before... */ - if (!vpt->rules.dict_def) tmpl_set_dict_def(vpt, dict); + if (!vpt->rules.attr.dict_def) tmpl_set_dict_def(vpt, dict); /* * Convert virtual &Attr-Foo to "%{Attr-Foo}" @@ -421,7 +429,9 @@ static bool pass2_fixup_cond_map(fr_cond_t *c, CONF_ITEM *ci, fr_dict_t const *d T_DOUBLE_QUOTED_STRING, NULL, &(tmpl_rules_t){ - .allow_unknown = true + .attr = { + .allow_unknown = true + } }); if (!vpt) { char *spaces, *text; @@ -489,7 +499,7 @@ static bool pass2_fixup_cond_map(fr_cond_t *c, CONF_ITEM *ci, fr_dict_t const *d return false; } - if (c->data.map->lhs->cast != FR_TYPE_NULL) { + if (tmpl_rules_cast(c->data.map->lhs) != FR_TYPE_NULL) { cf_log_err(map->ci, "Cannot cast virtual attribute %s to %s", map->lhs->name, fr_table_str_by_value(fr_value_box_type_table, c->data.map->lhs->type, "")); return false; @@ -532,13 +542,13 @@ static bool pass2_fixup_map(map_t *map, tmpl_rules_t const *rules, fr_dict_attr_ * FIXME: compile to attribute && handle * the conversion in map_to_vp(). */ - if (!pass2_fixup_tmpl(map, &map->lhs, map->ci, rules->dict_def)) { + if (!pass2_fixup_tmpl(map, &map->lhs, map->ci, rules->attr.dict_def)) { return false; } } if (tmpl_is_exec(map->lhs)) { - if (!pass2_fixup_tmpl(map, &map->lhs, map->ci, rules->dict_def)) { + if (!pass2_fixup_tmpl(map, &map->lhs, map->ci, rules->attr.dict_def)) { return false; } } @@ -547,7 +557,7 @@ static bool pass2_fixup_map(map_t *map, tmpl_rules_t const *rules, fr_dict_attr_ * Deal with undefined attributes now. */ if (tmpl_is_attr_unresolved(map->lhs)) { - if (!pass2_fixup_tmpl(map, &map->lhs, map->ci, rules->dict_def)) return false; + if (!pass2_fixup_tmpl(map, &map->lhs, map->ci, rules->attr.dict_def)) return false; } /* @@ -570,7 +580,7 @@ static bool pass2_fixup_map(map_t *map, tmpl_rules_t const *rules, fr_dict_attr_ * FIXME: compile to attribute && handle * the conversion in map_to_vp(). */ - if (!pass2_fixup_tmpl(map, &map->rhs, map->ci, rules->dict_def)) { + if (!pass2_fixup_tmpl(map, &map->rhs, map->ci, rules->attr.dict_def)) { return false; } } @@ -578,11 +588,11 @@ static bool pass2_fixup_map(map_t *map, tmpl_rules_t const *rules, fr_dict_attr_ fr_assert(!tmpl_is_regex_xlat_unresolved(map->rhs)); if (tmpl_is_attr_unresolved(map->rhs)) { - if (!pass2_fixup_tmpl(map, &map->rhs, map->ci, rules->dict_def)) return false; + if (!pass2_fixup_tmpl(map, &map->rhs, map->ci, rules->attr.dict_def)) return false; } if (tmpl_is_exec(map->rhs)) { - if (!pass2_fixup_tmpl(map, &map->rhs, map->ci, rules->dict_def)) { + if (!pass2_fixup_tmpl(map, &map->rhs, map->ci, rules->attr.dict_def)) { return false; } } @@ -670,7 +680,7 @@ static bool pass2_fixup_map_rhs(unlang_group_t *g, tmpl_rules_t const *rules) if (!gext->vpt) return true; return pass2_fixup_tmpl(map_list_head(&gext->map)->ci, &gext->vpt, - cf_section_to_item(g->cs), rules->dict_def); + cf_section_to_item(g->cs), rules->attr.dict_def); } static void unlang_dump(unlang_t *instruction, int depth) @@ -1314,7 +1324,7 @@ static unlang_t *compile_map(unlang_t *parent, unlang_compile_t *unlang_ctx, CON * We allow unknown attributes here. */ t_rules = *(unlang_ctx->rules); - t_rules.allow_unknown = true; + t_rules.attr.allow_unknown = true; RULES_VERIFY(&t_rules); modules = cf_section_find(cf_root(cs), "modules", NULL); @@ -1445,7 +1455,7 @@ static unlang_t *compile_update(unlang_t *parent, unlang_compile_t *unlang_ctx, * We allow unknown attributes here. */ t_rules = *(unlang_ctx->rules); - t_rules.allow_unknown = true; + t_rules.attr.allow_unknown = true; RULES_VERIFY(&t_rules); g = group_allocate(parent, cs, &update_ext); @@ -1504,7 +1514,7 @@ static unlang_t *compile_filter(unlang_t *parent, unlang_compile_t *unlang_ctx, * We allow unknown attributes here. */ t_rules = *(unlang_ctx->rules); - t_rules.allow_unknown = true; + t_rules.attr.allow_unknown = true; RULES_VERIFY(&t_rules); g = group_allocate(parent, cs, &filter_ext); @@ -1663,8 +1673,8 @@ static unlang_t *compile_edit_section(unlang_t *parent, unlang_compile_t *unlang * We allow unknown attributes here. */ t_rules = *(unlang_ctx->rules); - t_rules.allow_unknown = true; - t_rules.list_as_attr = true; + t_rules.attr.allow_unknown = true; + t_rules.attr.list_as_attr = true; RULES_VERIFY(&t_rules); c = *prev; @@ -1700,7 +1710,7 @@ static unlang_t *compile_edit_section(unlang_t *parent, unlang_compile_t *unlang name = cf_section_name1(cs); - slen = tmpl_afrom_attr_str(map, NULL, &map->lhs, name, &t_rules); + slen = tmpl_afrom_attr_str(map, NULL, &map->lhs, name, &t_rules.attr); if (slen <= 0) { cf_log_err(cs, "Failed parsing list reference %s", name); fail: @@ -1755,8 +1765,8 @@ static unlang_t *compile_edit_pair(unlang_t *parent, unlang_compile_t *unlang_ct * We allow unknown attributes here. */ t_rules = *(unlang_ctx->rules); - t_rules.allow_unknown = true; - t_rules.list_as_attr = true; + t_rules.attr.allow_unknown = true; + t_rules.attr.list_as_attr = true; RULES_VERIFY(&t_rules); c = *prev; @@ -2465,7 +2475,7 @@ static unlang_t *compile_switch(unlang_t *parent, unlang_compile_t *unlang_ctx, * We allow unknown attributes here. */ t_rules = *(unlang_ctx->rules); - t_rules.allow_unknown = true; + t_rules.attr.allow_unknown = true; RULES_VERIFY(&t_rules); name2 = cf_section_name2(cs); @@ -2519,7 +2529,7 @@ static unlang_t *compile_switch(unlang_t *parent, unlang_compile_t *unlang_ctx, * This is so that compile_case() can do attribute type * checks / casts against us. */ - if (!pass2_fixup_tmpl(g, &gext->vpt, cf_section_to_item(cs), unlang_ctx->rules->dict_def)) { + if (!pass2_fixup_tmpl(g, &gext->vpt, cf_section_to_item(cs), unlang_ctx->rules->attr.dict_def)) { error: talloc_free(g); return NULL; @@ -2548,8 +2558,8 @@ static unlang_t *compile_switch(unlang_t *parent, unlang_compile_t *unlang_ctx, } type = FR_TYPE_STRING; - if (gext->vpt->cast) { - type = gext->vpt->cast; + if (tmpl_rules_cast(gext->vpt)) { + type = tmpl_rules_cast(gext->vpt); } else if (tmpl_is_attr(gext->vpt)) { type = tmpl_da(gext->vpt)->type; @@ -2677,7 +2687,7 @@ static unlang_t *compile_case(unlang_t *parent, unlang_compile_t *unlang_ctx, CO * We allow unknown attributes here. */ t_rules = *(unlang_ctx->rules); - t_rules.allow_unknown = true; + t_rules.attr.allow_unknown = true; RULES_VERIFY(&t_rules); if (!parent || (parent->type != UNLANG_TYPE_SWITCH)) { @@ -2728,7 +2738,7 @@ static unlang_t *compile_case(unlang_t *parent, unlang_compile_t *unlang_ctx, CO * "switch" tmpl. */ if (tmpl_is_unresolved(vpt)) { - fr_type_t cast_type = switch_gext->vpt->cast; + fr_type_t cast_type = tmpl_rules_cast(switch_gext->vpt); fr_dict_attr_t const *da = NULL; if (tmpl_is_attr(switch_gext->vpt)) da = tmpl_da(switch_gext->vpt); @@ -2801,7 +2811,7 @@ static unlang_t *compile_foreach(unlang_t *parent, unlang_compile_t *unlang_ctx, * We allow unknown attributes here. */ t_rules = *(unlang_ctx->rules); - t_rules.allow_unknown = true; + t_rules.attr.allow_unknown = true; RULES_VERIFY(&t_rules); name2 = cf_section_name2(cs); @@ -3054,7 +3064,7 @@ static unlang_t *compile_if_subsection(unlang_t *parent, unlang_compile_t *unlan case COND_TYPE_TMPL: fr_assert(!tmpl_is_regex_xlat_unresolved(leaf->data.vpt)); if (!pass2_fixup_tmpl(leaf, &leaf->data.vpt, cf_section_to_item(cs), - unlang_ctx->rules->dict_def)) return false; + unlang_ctx->rules->attr.dict_def)) return false; break; /* @@ -3062,7 +3072,7 @@ static unlang_t *compile_if_subsection(unlang_t *parent, unlang_compile_t *unlan */ case COND_TYPE_MAP: if (!pass2_fixup_cond_map(leaf, cf_section_to_item(cs), - unlang_ctx->rules->dict_def)) return false; + unlang_ctx->rules->attr.dict_def)) return false; break; default: @@ -3216,7 +3226,7 @@ static unlang_t *compile_load_balance_subsection(unlang_t *parent, unlang_compil * We allow unknown attributes here. */ t_rules = *(unlang_ctx->rules); - t_rules.allow_unknown = true; + t_rules.attr.allow_unknown = true; RULES_VERIFY(&t_rules); /* @@ -3283,7 +3293,7 @@ static unlang_t *compile_load_balance_subsection(unlang_t *parent, unlang_compil /* * Fixup the templates */ - if (!pass2_fixup_tmpl(g, &gext->vpt, cf_section_to_item(cs), unlang_ctx->rules->dict_def)) { + if (!pass2_fixup_tmpl(g, &gext->vpt, cf_section_to_item(cs), unlang_ctx->rules->attr.dict_def)) { talloc_free(g); return NULL; } @@ -3429,7 +3439,7 @@ static unlang_t *compile_subrequest(unlang_t *parent, unlang_compile_t *unlang_c */ name2 = cf_section_name2(cs); if (!name2) { - dict = unlang_ctx->rules->dict_def; + dict = unlang_ctx->rules->attr.dict_def; packet_name = name2 = unlang_ctx->section_name2; goto get_packet_type; } @@ -3444,7 +3454,7 @@ static unlang_t *compile_subrequest(unlang_t *parent, unlang_compile_t *unlang_c slen = tmpl_afrom_attr_substr(parent, NULL, &vpt, &FR_SBUFF_IN(name2, talloc_array_length(name2) - 1), - NULL, unlang_ctx->rules); + NULL, &unlang_ctx->rules->attr); if (slen <= 0) { cf_log_perr(cs, "Invalid argument to 'subrequest', failed parsing packet-type"); return NULL; @@ -3466,7 +3476,7 @@ static unlang_t *compile_subrequest(unlang_t *parent, unlang_compile_t *unlang_c return NULL; } - dict = unlang_ctx->rules->dict_def; + dict = unlang_ctx->rules->attr.dict_def; packet_name = NULL; goto get_packet_type; } @@ -3478,7 +3488,7 @@ static unlang_t *compile_subrequest(unlang_t *parent, unlang_compile_t *unlang_c */ p = strchr(name2, '.'); if (!p) { - dict = unlang_ctx->rules->dict_def; + dict = unlang_ctx->rules->attr.dict_def; packet_name = name2; } else { @@ -3585,8 +3595,8 @@ get_packet_type: t_rules = *unlang_ctx->rules; t_rules.parent = unlang_ctx->rules; - t_rules.dict_def = dict; - t_rules.allow_foreign = false; + t_rules.attr.dict_def = dict; + t_rules.attr.allow_foreign = false; /* * Copy over the compilation context. This is mostly @@ -3674,9 +3684,9 @@ static unlang_t *compile_call(unlang_t *parent, unlang_compile_t *unlang_ctx, CO return NULL; } if ((dict != fr_dict_internal()) && fr_dict_internal() && - unlang_ctx->rules->dict_def && (unlang_ctx->rules->dict_def != dict)) { + unlang_ctx->rules->attr.dict_def && (unlang_ctx->rules->attr.dict_def != dict)) { cf_log_err(cs, "Cannot call server %s with namespace '%s' from namespaces '%s' - they have incompatible protocols", - server, fr_dict_root(dict)->name, fr_dict_root(unlang_ctx->rules->dict_def)->name); + server, fr_dict_root(dict)->name, fr_dict_root(unlang_ctx->rules->attr.dict_def)->name); return NULL; } @@ -3745,7 +3755,7 @@ static unlang_t *compile_caller(unlang_t *parent, unlang_compile_t *unlang_ctx, */ memcpy(&parent_rules, unlang_ctx->rules, sizeof(parent_rules)); memcpy(&t_rules, unlang_ctx->rules, sizeof(t_rules)); - parent_rules.dict_def = dict; + parent_rules.attr.dict_def = dict; t_rules.parent = &parent_rules; /* @@ -3973,13 +3983,13 @@ static unlang_t *compile_module(unlang_t *parent, unlang_compile_t *unlang_ctx, /* * Can't use "chap" in "dhcp". */ - if (inst->module->dict && *inst->module->dict && unlang_ctx->rules && unlang_ctx->rules->dict_def && - (unlang_ctx->rules->dict_def != fr_dict_internal()) && - (*(inst->module->dict) != unlang_ctx->rules->dict_def)) { + if (inst->module->dict && *inst->module->dict && unlang_ctx->rules && unlang_ctx->rules->attr.dict_def && + (unlang_ctx->rules->attr.dict_def != fr_dict_internal()) && + (*(inst->module->dict) != unlang_ctx->rules->attr.dict_def)) { cf_log_err(ci, "The \"%s\" module can only used with 'namespace = %s'. It cannot be used with 'namespace = %s'.", inst->module->name, fr_dict_root(*inst->module->dict)->name, - fr_dict_root(unlang_ctx->rules->dict_def)->name); + fr_dict_root(unlang_ctx->rules->attr.dict_def)->name); return NULL; } diff --git a/src/lib/unlang/edit.c b/src/lib/unlang/edit.c index fe1b549322..64f4d72d60 100644 --- a/src/lib/unlang/edit.c +++ b/src/lib/unlang/edit.c @@ -88,7 +88,7 @@ static int templatize_lhs(TALLOC_CTX *ctx, edit_result_t *out, request_t *reques * anything else. */ slen = tmpl_afrom_attr_str(ctx, NULL, &out->to_free, box->vb_strvalue, - &(tmpl_rules_t){ + &(tmpl_attr_rules_t){ .dict_def = request->dict, .prefix = TMPL_ATTR_REF_PREFIX_NO }); diff --git a/src/lib/unlang/xlat.h b/src/lib/unlang/xlat.h index a16096f071..0518a1d463 100644 --- a/src/lib/unlang/xlat.h +++ b/src/lib/unlang/xlat.h @@ -291,16 +291,20 @@ int xlat_flatten_compiled_argv(TALLOC_CTX *ctx, xlat_exp_t const ***argv, xlat_ bool xlat_async_required(xlat_exp_t const *xlat); + +ssize_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, + fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules); + ssize_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_t **head, fr_event_list_t *el, xlat_flags_t *flags, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); + fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules); ssize_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); + fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules); ssize_t xlat_print(fr_sbuff_t *in, xlat_exp_t const *node, fr_sbuff_escape_rules_t const *e_rules); @@ -330,9 +334,6 @@ int xlat_func_args(xlat_t *xlat, xlat_arg_parser_t const args[]) CC_HINT(nonnul int xlat_func_mono(xlat_t *xlat, xlat_arg_parser_t const *arg) CC_HINT(nonnull); -ssize_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); - /** Set a callback for global instantiation of xlat functions * * @param[in] _xlat function to set the callback for (as returned by xlat_register). diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index 02f33a2344..ccca6acc4b 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -76,7 +76,7 @@ int xlat_fmt_get_vp(fr_pair_t **out, request_t *request, char const *name) *out = NULL; if (tmpl_afrom_attr_str(request, NULL, &vpt, name, - &(tmpl_rules_t){ + &(tmpl_attr_rules_t){ .dict_def = request->dict, .prefix = TMPL_ATTR_REF_PREFIX_AUTO }) <= 0) return -4; @@ -1004,7 +1004,7 @@ static xlat_action_t xlat_func_debug_attr(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcur fmt = attr->vb_strvalue; if (tmpl_afrom_attr_str(request, NULL, &vpt, fmt, - &(tmpl_rules_t){ + &(tmpl_attr_rules_t){ .dict_def = request->dict, .prefix = TMPL_ATTR_REF_PREFIX_AUTO }) <= 0) { @@ -1375,8 +1375,10 @@ static xlat_action_t xlat_func_map(TALLOC_CTX *ctx, fr_dcursor_t *out, fr_value_box_t *vb; tmpl_rules_t attr_rules = { - .dict_def = request->dict, - .prefix = TMPL_ATTR_REF_PREFIX_AUTO + .attr = { + .dict_def = request->dict, + .prefix = TMPL_ATTR_REF_PREFIX_AUTO + } }; if (map_afrom_attr_str(request, &map, fmt_vb->vb_strvalue, &attr_rules, &attr_rules) < 0) { @@ -1584,12 +1586,16 @@ static xlat_action_t xlat_func_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, if (xlat_tokenize_ephemeral(rctx, &rctx->ex, unlang_interpret_event_list(request), &flags, &FR_SBUFF_IN(arg->vb_strvalue, arg->vb_length), - &(fr_sbuff_parse_rules_t){ .escapes = &escape_rules }, + &(fr_sbuff_parse_rules_t){ + .escapes = &escape_rules + }, &(tmpl_rules_t){ - .allow_unknown = false, - .allow_unresolved = false, - .allow_foreign = false, - .dict_def = request->dict, + .attr = { + .allow_unknown = false, + .allow_unresolved = false, + .allow_foreign = false, + .dict_def = request->dict + }, .at_runtime = true }) < 0) { RPEDEBUG("Failed parsing expansion"); @@ -2339,7 +2345,7 @@ static xlat_action_t xlat_func_pairs(TALLOC_CTX *ctx, fr_dcursor_t *out, fr_pair_t *vp; if (tmpl_afrom_attr_str(ctx, NULL, &vpt, in_head->vb_strvalue, - &(tmpl_rules_t){ + &(tmpl_attr_rules_t){ .dict_def = request->dict, .prefix = TMPL_ATTR_REF_PREFIX_AUTO }) <= 0) { @@ -3394,7 +3400,7 @@ static xlat_action_t protocol_encode_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, memcpy(&tp_encode, xctx->inst, sizeof(tp_encode)); /* const issues */ if (tmpl_afrom_attr_str(ctx, NULL, &vpt, in_head->vb_strvalue, - &(tmpl_rules_t){ + &(tmpl_attr_rules_t){ .dict_def = request->dict, .prefix = TMPL_ATTR_REF_PREFIX_AUTO }) <= 0) { diff --git a/src/lib/unlang/xlat_eval.c b/src/lib/unlang/xlat_eval.c index 5abbcd1310..bee412f756 100644 --- a/src/lib/unlang/xlat_eval.c +++ b/src/lib/unlang/xlat_eval.c @@ -1520,7 +1520,12 @@ ssize_t _xlat_eval(TALLOC_CTX *ctx, char **out, size_t outlen, request_t *reques */ len = xlat_tokenize_ephemeral(ctx, &node, unlang_interpret_event_list(request), NULL, &FR_SBUFF_IN(fmt, strlen(fmt)), - NULL, &(tmpl_rules_t){ .dict_def = request->dict }); + NULL, + &(tmpl_rules_t){ + .attr = { + .dict_def = request->dict + } + }); if (len == 0) { if (*out) { **out = '\0'; diff --git a/src/lib/unlang/xlat_expr.c b/src/lib/unlang/xlat_expr.c index de75451b56..8451f9750c 100644 --- a/src/lib/unlang/xlat_expr.c +++ b/src/lib/unlang/xlat_expr.c @@ -477,7 +477,7 @@ static xlat_exp_t *xlat_expr_cast_alloc(TALLOC_CTX *ctx, fr_type_t type) } static ssize_t tokenize_expression(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *input, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, + fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules, fr_token_t prev, fr_type_t type, fr_sbuff_parse_rules_t const *bracket_rules, fr_dict_attr_t const *da); @@ -496,7 +496,7 @@ static ssize_t tokenize_expression(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flag * int64_t. */ static ssize_t tokenize_field(TALLOC_CTX *input_ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *input, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, + fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules, fr_type_t type, fr_sbuff_parse_rules_t const *bracket_rules, fr_dict_attr_t const *da) { ssize_t slen; @@ -701,7 +701,7 @@ check_more: * @todo - also update the escaping rules, depending on kind of string we have. */ type = FR_TYPE_STRING; - } else { + } else { type = FR_TYPE_INT64; } } @@ -892,11 +892,11 @@ static size_t const expr_assignment_op_table_len = NUM_ELEMENTS(expr_assignment_ * A OP B */ static ssize_t tokenize_expression(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *input, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, + fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules, fr_token_t prev, fr_type_t type, fr_sbuff_parse_rules_t const *bracket_rules, fr_dict_attr_t const *da) { - xlat_exp_t *lhs = NULL, *rhs = NULL, *node; + xlat_exp_t *lhs, *rhs = NULL, *node; xlat_t *func = NULL; fr_token_t op; ssize_t slen; @@ -1082,7 +1082,7 @@ static const fr_sbuff_term_t operator_terms = FR_SBUFF_TERMS( ); ssize_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) + fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules) { ssize_t slen; fr_sbuff_parse_rules_t *bracket_rules = NULL; diff --git a/src/lib/unlang/xlat_priv.h b/src/lib/unlang/xlat_priv.h index d00aa77871..e5d967c8e6 100644 --- a/src/lib/unlang/xlat_priv.h +++ b/src/lib/unlang/xlat_priv.h @@ -154,6 +154,8 @@ typedef struct { size_t len; //!< Length of the output string. } xlat_out_t; +extern fr_dict_attr_t const *attr_cast_base; /* for xlat_expr.c */ + /* * Helper functions */ @@ -306,10 +308,10 @@ int xlat_register_expressions(void); * xlat_tokenize.c */ int xlat_tokenize_expansion(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, - tmpl_rules_t const *t_rules); + tmpl_attr_rules_t const *t_rules); int xlat_tokenize_function_args(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, - tmpl_rules_t const *rules); + tmpl_attr_rules_t const *rules); #ifdef __cplusplus diff --git a/src/lib/unlang/xlat_tokenize.c b/src/lib/unlang/xlat_tokenize.c index 5fe9e21a9d..9b6ca9e05e 100644 --- a/src/lib/unlang/xlat_tokenize.c +++ b/src/lib/unlang/xlat_tokenize.c @@ -170,10 +170,10 @@ void xlat_exp_free(xlat_exp_t **head) static int xlat_tokenize_string(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, bool brace, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules); + fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules); static inline int xlat_tokenize_alternation(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, - tmpl_rules_t const *t_rules, bool func_args) + tmpl_attr_rules_t const *t_rules, bool func_args) { xlat_exp_t *node; @@ -310,7 +310,7 @@ int xlat_validate_function_mono(xlat_exp_t *node) */ static inline int xlat_tokenize_function_mono(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, - tmpl_rules_t const *rules) + tmpl_attr_rules_t const *rules) { xlat_exp_t *node; xlat_t *func; @@ -448,7 +448,7 @@ int xlat_validate_function_args(xlat_exp_t *node) */ int xlat_tokenize_function_args(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, - tmpl_rules_t const *rules) + tmpl_attr_rules_t const *rules) { xlat_exp_t *node; xlat_t *func; @@ -569,7 +569,7 @@ static int xlat_resolve_virtual_attribute(xlat_exp_t *node, tmpl_t *vpt) * */ static inline int xlat_tokenize_attribute(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) + fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules) { ssize_t slen; tmpl_attr_error_t err; @@ -587,7 +587,7 @@ static inline int xlat_tokenize_attribute(TALLOC_CTX *ctx, xlat_exp_t **head, xl * and instead are "virtual" attributes like * Foreach-Variable-N. */ - tmpl_rules_t our_t_rules; + tmpl_attr_rules_t our_t_rules; if (t_rules) { memcpy(&our_t_rules, t_rules, sizeof(our_t_rules)); @@ -694,7 +694,7 @@ done: } int xlat_tokenize_expansion(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, - tmpl_rules_t const *t_rules) + tmpl_attr_rules_t const *t_rules) { size_t len; fr_sbuff_marker_t s_m; @@ -864,7 +864,7 @@ int xlat_tokenize_expansion(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *fl */ static int xlat_tokenize_string(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, bool brace, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) + fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules) { xlat_exp_t *node = NULL; size_t len; @@ -1325,11 +1325,11 @@ ssize_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_t **head, if (t_rules) our_t_rules = *t_rules; - our_t_rules.runtime_el = el; + our_t_rules.xlat.runtime_el = el; fr_strerror_clear(); /* Clear error buffer */ if (xlat_tokenize_string(ctx, head, flags, &our_in, - false, p_rules, &our_t_rules) < 0) return -fr_sbuff_used(&our_in); + false, p_rules, &our_t_rules.attr) < 0) return -fr_sbuff_used(&our_in); /* * Zero length expansion, return a zero length node. @@ -1369,7 +1369,7 @@ ssize_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_t **head, * - >0 on success which is the number of characters parsed. */ ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) + fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules) { fr_sbuff_t our_in = FR_SBUFF(in); ssize_t slen; @@ -1541,7 +1541,7 @@ ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *fla * - < 0 the negative offset of the parse failure. */ ssize_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in, - fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules) + fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules) { fr_sbuff_t our_in = FR_SBUFF(in); xlat_flags_t tmp_flags = {}; diff --git a/src/modules/rlm_cache/rlm_cache.c b/src/modules/rlm_cache/rlm_cache.c index accc1edc1a..f44e4378bd 100644 --- a/src/modules/rlm_cache/rlm_cache.c +++ b/src/modules/rlm_cache/rlm_cache.c @@ -841,7 +841,7 @@ xlat_action_t cache_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, slen = tmpl_afrom_attr_substr(ctx, NULL, &target, &FR_SBUFF_IN(attr->vb_strvalue, attr->vb_length), NULL, - &(tmpl_rules_t){ + &(tmpl_attr_rules_t){ .dict_def = request->dict, .prefix = TMPL_ATTR_REF_PREFIX_AUTO }); @@ -1041,7 +1041,9 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) */ { tmpl_rules_t parse_rules = { - .allow_foreign = true /* Because we don't know where we'll be called */ + .attr = { + .allow_foreign = true /* Because we don't know where we'll be called */ + } }; map_list_init(&inst->maps); diff --git a/src/modules/rlm_cache/serialize.c b/src/modules/rlm_cache/serialize.c index 45640b4086..fafbf44a0a 100644 --- a/src/modules/rlm_cache/serialize.c +++ b/src/modules/rlm_cache/serialize.c @@ -111,9 +111,11 @@ int cache_deserialize(rlm_cache_entry_t *c, fr_dict_t const *dict, char *in, ssi while (((size_t)(p - in)) < (size_t)inlen) { map_t *map = NULL; tmpl_rules_t parse_rules = { - .dict_def = dict, - .prefix = TMPL_ATTR_REF_PREFIX_NO - }; + .attr = { + .dict_def = dict, + .prefix = TMPL_ATTR_REF_PREFIX_NO + } + }; q = strchr(p, '\n'); if (!q) break; /* List should also be terminated with a \n */ diff --git a/src/modules/rlm_csv/rlm_csv.c b/src/modules/rlm_csv/rlm_csv.c index a033054389..9357aee192 100644 --- a/src/modules/rlm_csv/rlm_csv.c +++ b/src/modules/rlm_csv/rlm_csv.c @@ -758,7 +758,9 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) int lineno; FILE *fp; tmpl_rules_t parse_rules = { - .allow_foreign = true /* Because we don't know where we'll be called */ + .attr = { + .allow_foreign = true /* Because we don't know where we'll be called */ + } }; char buffer[8192]; diff --git a/src/modules/rlm_exec/rlm_exec.c b/src/modules/rlm_exec/rlm_exec.c index 458bfcbdbf..9caf02d2ee 100644 --- a/src/modules/rlm_exec/rlm_exec.c +++ b/src/modules/rlm_exec/rlm_exec.c @@ -243,9 +243,11 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) &FR_SBUFF_IN(inst->program, strlen(inst->program)), T_BACK_QUOTED_STRING, NULL, &(tmpl_rules_t) { - .allow_foreign = true, - .allow_unresolved = false, - .allow_unknown = false + .attr = { + .allow_foreign = true, + .allow_unresolved = false, + .allow_unknown = false + } }); if (!inst->tmpl) { char *spaces, *text; diff --git a/src/modules/rlm_expr/rlm_expr.c b/src/modules/rlm_expr/rlm_expr.c index 974ae8da99..d84e89b18f 100644 --- a/src/modules/rlm_expr/rlm_expr.c +++ b/src/modules/rlm_expr/rlm_expr.c @@ -217,7 +217,9 @@ static bool get_number(request_t *request, char const **string, int64_t *answer) slen = tmpl_afrom_attr_substr(request, NULL, &vpt, &FR_SBUFF_IN(p, strlen(p)), &p_rules, - &(tmpl_rules_t){ .dict_def = request->dict }); + &(tmpl_attr_rules_t){ + .dict_def = request->dict + }); if (slen <= 0) { RPEDEBUG("Failed parsing attribute name '%s'", p); return false; diff --git a/src/modules/rlm_json/rlm_json.c b/src/modules/rlm_json/rlm_json.c index 079f6cf71a..187073430d 100644 --- a/src/modules/rlm_json/rlm_json.c +++ b/src/modules/rlm_json/rlm_json.c @@ -198,7 +198,9 @@ static xlat_action_t json_encode_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, slen = tmpl_afrom_attr_substr(ctx, NULL, &vpt, &sbuff, &json_arg_parse_rules, - &(tmpl_rules_t){ .dict_def = request->dict }); + &(tmpl_attr_rules_t){ + .dict_def = request->dict + }); if (slen <= 0) { fr_sbuff_set(&sbuff, (size_t)(slen * -1)); REMARKER(fr_sbuff_start(&sbuff), fr_sbuff_used(&sbuff), "%s", fr_strerror()); diff --git a/src/modules/rlm_ldap/rlm_ldap.c b/src/modules/rlm_ldap/rlm_ldap.c index 4a722cb125..e848b1ec85 100644 --- a/src/modules/rlm_ldap/rlm_ldap.c +++ b/src/modules/rlm_ldap/rlm_ldap.c @@ -2314,7 +2314,9 @@ if (inst->handle_config.tls_min_version_str) { */ { tmpl_rules_t parse_rules = { - .allow_foreign = true /* Because we don't know where we'll be called */ + .attr = { + .allow_foreign = true /* Because we don't know where we'll be called */ + } }; update = cf_section_find(conf, "update", NULL); diff --git a/src/modules/rlm_linelog/rlm_linelog.c b/src/modules/rlm_linelog/rlm_linelog.c index 474a63f1bc..2abb1e4dcd 100644 --- a/src/modules/rlm_linelog/rlm_linelog.c +++ b/src/modules/rlm_linelog/rlm_linelog.c @@ -524,9 +524,11 @@ static unlang_action_t CC_HINT(nonnull) mod_do_linelog(rlm_rcode_t *p_result, mo cf_pair_value_quote(cp), NULL, &(tmpl_rules_t){ - .dict_def = request->dict, - .allow_unknown = true, - .allow_unresolved = false, + .attr = { + .dict_def = request->dict, + .allow_unknown = true, + .allow_unresolved = false, + }, .at_runtime = true }); if (!vpt) { diff --git a/src/modules/rlm_python/rlm_python.c b/src/modules/rlm_python/rlm_python.c index 12931d4a0b..93fe9f4588 100644 --- a/src/modules/rlm_python/rlm_python.c +++ b/src/modules/rlm_python/rlm_python.c @@ -324,7 +324,7 @@ static void mod_vptuple(TALLOC_CTX *ctx, module_ctx_t const *mctx, request_t *re } if (tmpl_afrom_attr_str(ctx, NULL, &dst, s1, - &(tmpl_rules_t){ + &(tmpl_attr_rules_t){ .dict_def = request->dict, .list_def = PAIR_LIST_REPLY }) <= 0) { diff --git a/src/modules/rlm_radius/rlm_radius.c b/src/modules/rlm_radius/rlm_radius.c index 05306d3615..be60be909d 100644 --- a/src/modules/rlm_radius/rlm_radius.c +++ b/src/modules/rlm_radius/rlm_radius.c @@ -344,7 +344,9 @@ static int status_check_update_parse(TALLOC_CTX *ctx, void *out, UNUSED void *pa */ { tmpl_rules_t parse_rules = { - .allow_foreign = true /* Because we don't know where we'll be called */ + .attr = { + .allow_foreign = true /* Because we don't know where we'll be called */ + } }; rcode = map_afrom_cs(ctx, head, cs, &parse_rules, &parse_rules, unlang_fixup_update, NULL, 128); diff --git a/src/modules/rlm_rest/rest.c b/src/modules/rlm_rest/rest.c index 5194ce89bf..73c0abf045 100644 --- a/src/modules/rlm_rest/rest.c +++ b/src/modules/rlm_rest/rest.c @@ -736,7 +736,7 @@ static int rest_decode_post(UNUSED rlm_rest_t const *instance, UNUSED rlm_rest_s RDEBUG2("Parsing attribute \"%pV\"", fr_box_strvalue_len(name, curl_len)); if (tmpl_afrom_attr_str(request, NULL, &dst, name, - &(tmpl_rules_t){ + &(tmpl_attr_rules_t){ .prefix = TMPL_ATTR_REF_PREFIX_NO, .dict_def = request->dict, .list_def = PAIR_LIST_REPLY @@ -1024,7 +1024,7 @@ static int json_pair_alloc(rlm_rest_t const *instance, rlm_rest_section_t const RDEBUG2("Parsing attribute \"%s\"", name); if (tmpl_afrom_attr_str(request, NULL, &dst, name, - &(tmpl_rules_t){ + &(tmpl_attr_rules_t){ .prefix = TMPL_ATTR_REF_PREFIX_NO, .dict_def = request->dict, .list_def = PAIR_LIST_REPLY diff --git a/src/modules/rlm_smtp/rlm_smtp.c b/src/modules/rlm_smtp/rlm_smtp.c index 513fe0b57b..c81a85c64c 100644 --- a/src/modules/rlm_smtp/rlm_smtp.c +++ b/src/modules/rlm_smtp/rlm_smtp.c @@ -117,9 +117,11 @@ static int cf_table_parse_tmpl(TALLOC_CTX *ctx, void *out, UNUSED void *parent, tmpl_t *vpt; static tmpl_rules_t rules = { - .allow_unknown = true, - .allow_unresolved = true, - .allow_foreign = true + .attr = { + .allow_unknown = true, + .allow_unresolved = true, + .allow_foreign = true + } }; if (!tmpl) { @@ -1054,10 +1056,12 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) */ { tmpl_rules_t parse_rules = { - .allow_foreign = true, /* Because we don't know where we'll be called */ - .allow_unknown = true, - .allow_unresolved = true, - .prefix = TMPL_ATTR_REF_PREFIX_AUTO, + .attr = { + .allow_foreign = true, /* Because we don't know where we'll be called */ + .allow_unknown = true, + .allow_unresolved = true, + .prefix = TMPL_ATTR_REF_PREFIX_AUTO, + } }; if (map_afrom_cs(inst, &inst->header_maps, header, -- 2.47.2