From fa15bc5a97bec20697b7b1c5c7e906028cf08116 Mon Sep 17 00:00:00 2001 From: "Alan T. DeKok" Date: Wed, 20 Dec 2023 17:33:52 -0500 Subject: [PATCH] struct fixes for radius_legacy_map_apply() parse structs from RHS strings and various other cleanups relative attributes on multiple lines in SQL aren't supported. inter-attribute copies are permitted for structural types tests still need to be finalized --- src/lib/server/map.c | 10 +++++-- src/lib/server/pairmove.c | 19 ++++++++++++- src/lib/server/tmpl_tokenize.c | 32 ++++++++++++++-------- src/tests/modules/sql_sqlite/nested.attrs | 3 +- src/tests/modules/sql_sqlite/nested.unlang | 2 +- 5 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/lib/server/map.c b/src/lib/server/map.c index d07c2f313bb..d8f2f745268 100644 --- a/src/lib/server/map.c +++ b/src/lib/server/map.c @@ -2526,12 +2526,16 @@ int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, char const *lhs, char const * quote, value_parse_rules_quoted[quote], &my_rules); if (slen <= 0) goto error; - } else if (!rhs[0]) { - MEM(map->rhs = tmpl_alloc(map, TMPL_TYPE_DATA, T_BARE_WORD, "", 0)); + } else if (!rhs[0] || !my_rules.enumv || (my_rules.enumv->type == FR_TYPE_STRING)) { - (void) fr_value_box_strdup(map->rhs, tmpl_value(map->rhs), NULL, "", false); + MEM(map->rhs = tmpl_alloc(map, TMPL_TYPE_DATA, T_BARE_WORD, rhs, strlen(rhs))); + + (void) fr_value_box_strdup(map->rhs, tmpl_value(map->rhs), NULL, rhs, false); } else { + /* + * Parse it as the given data type. + */ slen = tmpl_afrom_substr(map, &map->rhs, &FR_SBUFF_IN(rhs, strlen(rhs)), T_BARE_WORD, value_parse_rules_unquoted[T_BARE_WORD], &my_rules); if (slen <= 0) goto error; diff --git a/src/lib/server/pairmove.c b/src/lib/server/pairmove.c index e63f25e58e6..ca04415ab7d 100644 --- a/src/lib/server/pairmove.c +++ b/src/lib/server/pairmove.c @@ -317,6 +317,7 @@ static int radius_legacy_map_apply_structural(request_t *request, map_t const *m TALLOC_CTX *ctx; fr_value_box_t *to_free = NULL; fr_value_box_t const *box; + fr_pair_parse_t root, relative; /* * Finds both the correct ctx and nested list. @@ -431,6 +432,7 @@ static int radius_legacy_map_apply_structural(request_t *request, map_t const *m add: vp = fr_pair_afrom_da_nested(ctx, list, da); if (!vp) { + fail: TALLOC_FREE(to_free); return -1; } @@ -441,7 +443,22 @@ static int radius_legacy_map_apply_structural(request_t *request, map_t const *m */ if (!box->vb_strvalue[0]) break; - fr_assert(0); + /* + * Parse the string as a list of pairs. + */ + root = (fr_pair_parse_t) { + .ctx = vp, + .da = vp->da, + .list = &vp->vp_group, + .allow_compare = false, + .tainted = box->tainted, + }; + relative = (fr_pair_parse_t) { }; + + if (fr_pair_list_afrom_substr(&root, &relative, &FR_SBUFF_IN(box->vb_strvalue, box->vb_length)) < 0) { + RPEDEBUG("Failed parsing string '%pV' as attribute list", box); + goto fail; + } break; default: diff --git a/src/lib/server/tmpl_tokenize.c b/src/lib/server/tmpl_tokenize.c index 78612de8577..23d013fcc28 100644 --- a/src/lib/server/tmpl_tokenize.c +++ b/src/lib/server/tmpl_tokenize.c @@ -3014,6 +3014,8 @@ static ssize_t tmpl_afrom_enum(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, */ if (t_rules->at_runtime) return 0; + ERROR("UNRESOLVED %d", __LINE__); + tmpl_init(vpt, TMPL_TYPE_DATA_UNRESOLVED, T_BARE_WORD, fr_sbuff_start(&our_in), fr_sbuff_used(&our_in), t_rules); vpt->data.unescaped = str; @@ -3222,12 +3224,24 @@ fr_slen_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, FR_SBUFF_ERROR_RETURN(&our_in); } + slen = fr_sbuff_used(&our_in); + + data_unresolved: + if (t_rules->at_runtime) { + tmpl_init(vpt, TMPL_TYPE_DATA, quote, + fr_sbuff_start(&our_in), slen, t_rules); + + /* + * @todo - we have no idea if this is tainted or not. + */ + fr_value_box_strdup_shallow(tmpl_value(vpt), t_rules->enumv, str, false); + break; + } + tmpl_init(vpt, TMPL_TYPE_DATA_UNRESOLVED, quote, - fr_sbuff_start(&our_in), fr_sbuff_used(&our_in), t_rules); + fr_sbuff_start(&our_in), slen, t_rules); vpt->data.unescaped = str; - *out = vpt; - - FR_SBUFF_SET_RETURN(in, &our_in); + break; case T_SINGLE_QUOTED_STRING: /* @@ -3242,9 +3256,7 @@ fr_slen_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, slen = fr_sbuff_out_aunescape_until(vpt, &str, &our_in, SIZE_MAX, p_rules ? p_rules->terminals : NULL, p_rules ? p_rules->escapes : NULL); - tmpl_init(vpt, TMPL_TYPE_DATA_UNRESOLVED, quote, fr_sbuff_start(&our_in), slen, t_rules); - vpt->data.unescaped = str; - break; + goto data_unresolved; case T_DOUBLE_QUOTED_STRING: { @@ -3275,11 +3287,7 @@ fr_slen_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, */ if (xlat_to_string(vpt, &str, &head)) { TALLOC_FREE(head); - - tmpl_init(vpt, TMPL_TYPE_DATA_UNRESOLVED, quote, - fr_sbuff_start(&our_in), slen, t_rules); - vpt->data.unescaped = str; /* Store the unescaped string for parsing later */ - break; + goto data_unresolved; } } diff --git a/src/tests/modules/sql_sqlite/nested.attrs b/src/tests/modules/sql_sqlite/nested.attrs index 302231fea00..40131c09370 100644 --- a/src/tests/modules/sql_sqlite/nested.attrs +++ b/src/tests/modules/sql_sqlite/nested.attrs @@ -11,5 +11,4 @@ NAS-IP-Address = "1.2.3.4" # Packet-Type == Access-Accept Idle-Timeout == 3600 -Digest-Attributes == { } -#Digest-Attributes == { Nonce == "dcd98b7102dd2f0e8b11d0f600bfb0c093", Method == "Invite", URI == "sip:bob@biloxi.com" } +Digest-Attributes == { Nonce == "dcd98b7102dd2f0e8b11d0f600bfb0c093", Method == "Invite", URI == "sip:bob@biloxi.com" } diff --git a/src/tests/modules/sql_sqlite/nested.unlang b/src/tests/modules/sql_sqlite/nested.unlang index b6634094820..491b06d968f 100644 --- a/src/tests/modules/sql_sqlite/nested.unlang +++ b/src/tests/modules/sql_sqlite/nested.unlang @@ -22,7 +22,7 @@ if (%sql("${insert_into_radreply} ('user_auth_nested', 'Idle-Timeout', ':=', '36 test_fail } -if (%sql("${insert_into_radreply} ('user_auth_nested', 'Digest-Attributes', ':=', '')") != "1") { +if (%sql("${insert_into_radreply} ('user_auth_nested', 'Digest-Attributes', ':=', 'Nonce = \"dcd98b7102dd2f0e8b11d0f600bfb0c093\", Method = \"Invite\", URI = \"sip:bob@biloxi.com\"')") != "1") { test_fail } -- 2.47.3