#include <freeradius-devel/server/tmpl.h>
#include <freeradius-devel/server/tmpl_dcursor.h>
+#include <freeradius-devel/unlang/interpret.h>
+
#include <freeradius-devel/util/debug.h>
#include <freeradius-devel/util/base16.h>
#include <freeradius-devel/util/pair_legacy.h>
*
* @param[in] ctx where to allocate the map.
* @param[out] out Where to write the new map (must be freed with talloc_free()).
+ * @param[in] request the request
* @param[in] lhs of map
* @param[in] op of map
* @param[in] rhs of map
* - 0 on success.
* - -1 on failure.
*/
-int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, char const *lhs, char const *op, char const *rhs,
+int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, request_t *request, char const *lhs, char const *op, char const *rhs,
tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules)
{
ssize_t slen;
my_rules = *rhs_rules;
my_rules.at_runtime = true;
+ my_rules.xlat.runtime_el = unlang_interpret_event_list(request);
my_rules.enumv = tmpl_attr_tail_da(map->lhs);
/*
goto parse_quoted;
} else if (rhs[0] == '\'') {
+ size_t len;
+
quote = T_SINGLE_QUOTED_STRING;
parse_quoted:
- slen = tmpl_afrom_substr(map, &map->rhs, &FR_SBUFF_IN(rhs, strlen(rhs)),
+ len = strlen(rhs + 1);
+ if (len == 1) {
+ if (rhs[1] != rhs[0]) {
+ fr_strerror_const("Invalid string on right side");
+ return -1;
+ }
+
+ rhs = "";
+ goto alloc_empty;
+ }
+
+ slen = tmpl_afrom_substr(map, &map->rhs, &FR_SBUFF_IN(rhs + 1, len - 1),
quote, value_parse_rules_quoted[quote], &my_rules);
- if (slen <= 0) goto error;
+ if (slen < 0) goto error;
+
+ if (slen == 0) {
+ rhs = "";
+ goto alloc_empty;
+ }
+
+ ERROR("CONVERT %s --> %s", rhs, map->rhs->name);
+
+ /*
+ * Ignore any extra data after the string.
+ */
} else if (rhs[0] == '&') {
/*
if (slen <= 0) goto error;
} else if (!rhs[0] || !my_rules.enumv || (my_rules.enumv->type == FR_TYPE_STRING)) {
+ quote = T_BARE_WORD;
- MEM(map->rhs = tmpl_alloc(map, TMPL_TYPE_DATA, T_BARE_WORD, rhs, strlen(rhs)));
+ alloc_empty:
+ MEM(map->rhs = tmpl_alloc(map, TMPL_TYPE_DATA, quote, rhs, strlen(rhs)));
(void) fr_value_box_strdup(map->rhs, tmpl_value(map->rhs), NULL, rhs, false);
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;
+ }
+
+ if (tmpl_needs_resolving(map->rhs)) {
+ tmpl_res_rules_t tr_rules = (tmpl_res_rules_t) {
+ .dict_def = lhs_rules->attr.dict_def,
+ .enumv = tmpl_attr_tail_da(map->lhs)
+ };
+
+ fr_assert(tmpl_is_data_unresolved(map->rhs));
- fr_assert(!tmpl_needs_resolving(map->rhs));
+ if (tmpl_resolve(map->rhs, &tr_rules) < 0) goto error;
}
/*
tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules,
fr_sbuff_parse_rules_t const *p_rules);
-int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, char const *lhs, char const *op, char const *rhs,
+int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, request_t *request, char const *lhs, char const *op, char const *rhs,
tmpl_rules_t const *lhs_rules, tmpl_rules_t const *rhs_rules) CC_HINT(nonnull);
int map_to_vp(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request,
while (rlm_sql_fetch_row(&row, inst, request, handle) == RLM_SQL_OK) {
map_t *map;
- if (map_afrom_fields(ctx, &map, row[2], row[4], row[3], &lhs_rules, &rhs_rules) < 0) {
+ if (map_afrom_fields(ctx, &map, request, row[2], row[4], row[3], &lhs_rules, &rhs_rules) < 0) {
RPEDEBUG("Error parsing user data from database result");
(inst->driver->sql_finish_select_query)(*handle, &inst->config);
return -1;