From: Alan T. DeKok Date: Mon, 20 Dec 2021 14:05:02 +0000 (-0500) Subject: use new hack function, so that we support T_OP_EQ and T_OP_SET X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a3f98d7b3c7b309d0c2891fb29096dccb115add9;p=thirdparty%2Ffreeradius-server.git use new hack function, so that we support T_OP_EQ and T_OP_SET --- diff --git a/src/lib/unlang/edit.c b/src/lib/unlang/edit.c index 1dce9d89c6..c7e54b2100 100644 --- a/src/lib/unlang/edit.c +++ b/src/lib/unlang/edit.c @@ -561,21 +561,48 @@ static unlang_action_t process_edit(rlm_rcode_t *p_result, request_t *request, u case UNLANG_EDIT_CHECK_LHS: check_lhs: /* - * Find the LHS VP. If it doesn't exist, - * return an error. Note that this means - * ":=" and "=" don't yet work. - * - * @todo - the "find vp" function needs - * to return the parent list, for - * T_OP_SET and T_OP_EQ, so that we can - * add the newly created attribute to the - * parent list. + * Find the LHS VP to edit. */ if (tmpl_find_vp(&state->lhs.vp, request, state->lhs.vpt) < 0) { - if (map->op == T_OP_EQ) goto next; + fr_pair_t *parent; - REDEBUG("Failed to find %s", state->lhs.vpt->name); - goto error; + /* + * Get the list. + */ + if ((map->op != T_OP_SET) && (map->op != T_OP_EQ)) { + REDEBUG("Failed to find %s", state->lhs.vpt->name); + goto error; + } + + if (tmpl_is_attr(state->lhs.vpt) && fr_type_is_structural(tmpl_da(state->lhs.vpt)->type)) { + REDEBUG("Can't edit structural %s", state->lhs.vpt->name); + goto error; + } + + fr_assert(!tmpl_is_list(state->lhs.vpt)); + + /* + * The VP doesn't exist, get the list it's in. + */ + parent = tmpl_get_list(request, state->lhs.vpt); + if (!parent) { + REDEBUG("Failed to find list for %s", state->lhs.vpt->name); + goto error; + } + + /* + * Add the new VP to the parent. The edit list code is safe for multiple + * edits of the same VP, so we don't have to do anything else here. + */ + MEM(state->lhs.vp = fr_pair_afrom_da(parent, tmpl_da(state->lhs.vpt))); + if (fr_edit_list_insert_pair_tail(state->el, &parent->vp_group, state->lhs.vp) < 0) goto error; + + } else if (map->op == T_OP_EQ) { + /* + * We're setting the value, but the attribute already exists. This is a + * NOOP. + */ + goto next; } /*