26RCSID(
"$Id: df1b35e839bb2733cead6c359bd5ec28eb75f095 $")
28#include <freeradius-devel/server/paircmp.h>
29#include <freeradius-devel/server/pairmove.h>
30#include <freeradius-devel/server/tmpl_dcursor.h>
32#include <freeradius-devel/util/debug.h>
33#include <freeradius-devel/util/calc.h>
34#include <freeradius-devel/util/pair_legacy.h>
36#include <freeradius-devel/protocol/radius/rfc2865.h>
37#include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
81 if ((edited[i] ==
vp) && (
vp->
da == da)) {
136 if (edited[i] ==
vp)
continue;
175 bool relink =
false, found;
200 fr_pair_remove(from, (_vp)); \
201 (_vp)->op = T_OP_EQ; \
209 for (old = fr_pair_list_head(to), j = 0; \
210 pair_find_next_by_da(to, &old, &j, edited, vp->da); \
211 old = fr_pair_list_next(to, old), j++)
229 if (!edited)
goto do_remove;
247 if (!edited)
goto do_remove;
271 if (!edited)
goto do_add;
290 if (((op ==
T_OP_LE) && (rcode > 0)) ||
291 ((op ==
T_OP_GE) && (rcode < 0))) {
296 if (found)
goto do_remove;
300 if (!edited)
goto do_add;
310 if (!edited)
goto do_add;
379 if (rhs->vp_type != da->type) {
399 TALLOC_FREE(to_free);
403 TALLOC_FREE(to_free);
423 for (child = map_list_next(&map->
child, NULL);
425 child = map_list_next(&map->
child, child)) {
441 if (rhs->vp_type !=
vp->vp_type) {
472 TALLOC_FREE(to_free);
481 if (box->vb_strvalue[0]) {
490 .list = &
vp->vp_group,
491 .dict =
vp->
da->dict,
493 .allow_compare =
false,
494 .tainted = box->tainted,
499 RPEDEBUG(
"Failed parsing string '%pV' as attribute list", box);
500 TALLOC_FREE(to_free);
505 TALLOC_FREE(to_free);
524 if (!
vp)
return NULL;
608 if ((num >= 0) || (num ==
NUM_LAST)) {
672 RWDEBUG(
"Failed creating attribute %s", map->
lhs->name);
745 if (rhs->vp_type != da->type) {
773 TALLOC_FREE(to_free);
778 TALLOC_FREE(to_free);
795 if (rcode < 0)
goto fail;
797 if (rcode != 0)
break;
804 if (rcode < 0)
goto fail;
821 TALLOC_FREE(to_free);
829 for (map = map_list_head(list);
831 map = map_list_next(list, map)) {
833 map->
rhs ? map->
rhs->name :
"{ ... }");
914 if ((rcode >= 0) && dst.vb_bool)
break;
917 TALLOC_FREE(to_free);
920 if (rcode < 0)
return rcode;
static uint8_t request[4]
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
int fr_value_calc_binary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t hint, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
Calculate DST = A OP B.
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
static void * fr_dcursor_set_current(fr_dcursor_t *cursor, void *item)
Set the cursor to a specified item.
fr_dict_t const * fr_dict_internal(void)
#define RPEDEBUG(fmt,...)
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_BOOL
A truth value.
int fr_pair_append_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da)
Alloc a new fr_pair_t (and append)
int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from)
Duplicate a list of pairs.
fr_pair_list_t * fr_pair_parent_list(fr_pair_t const *vp)
Return a pointer to the parent pair list.
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
fr_pair_t * fr_pair_parent(fr_pair_t const *vp)
Return a pointer to the parent pair.
void fr_pair_replace(fr_pair_list_t *list, fr_pair_t *to_replace, fr_pair_t *vp)
Replace a given VP.
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
int fr_pair_prepend(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the start of the list.
fr_slen_t fr_pair_list_afrom_substr(fr_pair_parse_t const *root, fr_pair_parse_t *relative, fr_sbuff_t *in)
Parse a fr_pair_list_t from a substring.
int paircmp_pairs(UNUSED request_t *request, fr_pair_t const *check, fr_pair_t *vp)
Compares check and vp by value.
static void pair_relink(fr_pair_list_t *to, fr_pair_t *const *edited)
Update the "to" list with the changes which radius_pairmove() has made.
static int radius_legacy_map_to_vp(request_t *request, fr_pair_t *parent, map_t const *map)
static bool pair_find_next_by_da(fr_pair_list_t const *list, fr_pair_t **vp_p, size_t *index_p, fr_pair_t *const *edited, fr_dict_attr_t const *da)
Find the next unedited pair with a matching attribute.
void radius_pairmove(request_t *request, fr_pair_list_t *to, fr_pair_list_t *from)
Merge the "from" list into the "to" list, using the operator of each pair.
int radius_legacy_map_cmp(request_t *request, map_t const *map)
static fr_pair_t * legacy_pair_build(fr_pair_t *parent, fr_dcursor_t *cursor, fr_dict_attr_t const *da, void *uctx)
Build the relevant pairs at each level.
int radius_legacy_map_apply(request_t *request, map_t const *map, fr_edit_list_t *el)
Move a map using the operators from the old pairmove functionality.
static bool pair_find_by_da(size_t *index_p, fr_pair_list_t const *list, fr_pair_t *const *edited, fr_dict_attr_t const *da)
Find the first unedited pair with a matching attribute.
static int radius_legacy_map_apply_structural(request_t *request, map_t const *map, fr_pair_t *vp)
int radius_legacy_map_list_apply(request_t *request, map_list_t const *list, fr_edit_list_t *el)
static bool request_attr_is_list(fr_dict_attr_t const *da)
#define FR_SBUFF_IN(_start, _len_or_end)
int tmpl_find_vp(fr_pair_t **out, request_t *request, tmpl_t const *vpt))
Returns the first VP matching a tmpl_t.
static int16_t tmpl_attr_tail_num(tmpl_t const *vpt)
Return the last attribute reference's attribute number.
#define tmpl_contains_xlat(vpt)
#define tmpl_is_xlat(vpt)
#define tmpl_value(_tmpl)
#define tmpl_is_attr(vpt)
static fr_dict_attr_t const * tmpl_list(tmpl_t const *vpt)
#define tmpl_pair_list_and_ctx(_ctx, _head, _request, _ref, _list)
Determine the correct context and list head.
#define tmpl_is_data(vpt)
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
#define tmpl_is_regex(vpt)
#define tmpl_aexpand(_ctx, _out, _request, _vpt, _escape, _escape_ctx)
Expand a tmpl to a C type, allocing a new buffer to hold the string.
fr_token_t op
The operator that controls insertion of the dst attribute.
tmpl_t * lhs
Typically describes the attribute to add, modify or compare.
map_list_t child
parent map, for nested ones
tmpl_t * rhs
Typically describes a literal value or a src attribute to copy or compare.
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
void tmpl_dcursor_clear(tmpl_dcursor_ctx_t *cc)
Clear any temporary state allocations.
#define tmpl_dcursor_build_init(_err, _ctx, _cc, _cursor, _request, _vpt, _build, _uctx)
#define tmpl_dcursor_init(_err, _ctx, _cc, _cursor, _request, _vpt)
Maintains state between cursor calls.
char const * fr_tokens[T_TOKEN_LAST]
const bool fr_comparison_op[T_TOKEN_LAST]
static fr_event_list_t * el
int fr_edit_list_pair_delete(fr_edit_list_t *el, fr_pair_list_t *list, fr_pair_t *vp)
Delete a VP.
int fr_edit_list_save_pair_value(fr_edit_list_t *el, fr_pair_t *vp)
Record the value of a leaf fr_value_box_t.
int fr_edit_list_free_pair_children(fr_edit_list_t *el, fr_pair_t *vp)
Free children of a structural pair.
#define fr_edit_list_insert_pair_tail(_el, _list, _vp)
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
fr_pair_t * fr_pair_remove(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list without freeing.
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
void fr_pair_list_prepend(fr_pair_list_t *dst, fr_pair_list_t *src)
Move a list of fr_pair_t from a temporary list to the head of a destination list.
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
size_t fr_pair_list_num_elements(fr_pair_list_t const *list)
Get the length of a list of fr_pair_t.
#define add(_type, _out, _in)
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
#define fr_type_is_structural(_x)
#define fr_type_is_leaf(_x)
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
void fr_value_box_mark_unsafe(fr_value_box_t *vb)
Mark a value-box as "unsafe".
int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert one type of fr_value_box_t to another.
int fr_value_box_cmp_op(fr_token_t op, fr_value_box_t const *a, fr_value_box_t const *b)
Compare two attributes using an operator.
void fr_value_box_strdup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Assign a buffer containing a nul terminated string to a box, but don't copy it.