a->state = COND_EVAL_STATE_INIT;
goto redo;
}
+
+/** Evaluate a map as if it is a condition.
+ *
+ */
+int fr_cond_eval_map(request_t *request, map_t const *map)
+{
+ fr_cond_t cond;
+
+ memset(&cond, 0, sizeof(cond));
+
+ /*
+ * Convert !* and =* to existence checks.
+ */
+ switch (map->op) {
+ case T_OP_CMP_FALSE:
+ cond.negate = true;
+ FALL_THROUGH;
+
+ case T_OP_CMP_TRUE:
+ cond.type = COND_TYPE_TMPL;
+ cond.data.vpt = UNCONST(tmpl_t *, map->lhs);
+ break;
+
+ default:
+ cond.type = COND_TYPE_MAP;
+ cond.data.map = UNCONST(map_t *, map);
+ break;
+ }
+
+ return cond_eval(request, RLM_MODULE_NOOP, &cond);
+}
RCSIDH(cond_eval_h, "$Id$")
#include <freeradius-devel/server/request.h>
+#include <freeradius-devel/server/map.h>
#include <freeradius-devel/util/value.h>
#ifdef __cplusplus
int cond_eval_async(request_t *request, fr_cond_async_t *a);
+int fr_cond_eval_map(request_t *request, map_t const *map);
+
#ifdef __cplusplus
}
#endif
PAIR_LIST const *pl;
fr_pair_list_t list;
bool fall_through = false;
+ bool match = true;
/*
* Figure out which entry to match on.
/*
* Realize the map to a list of VPs
- *
- * @todo convert the pl->check to fr_cond_t, and just use that!
*/
while ((map = fr_dlist_next(&pl->check, map))) {
+ int rcode;
fr_pair_list_t tmp_list;
- fr_pair_list_init(&tmp_list);
- if (map_to_vp(request->control_ctx, &tmp_list, request, map, NULL) < 0) {
- fr_pair_list_free(&list);
- RPWARN("Failed parsing map for check item, skipping entry");
+
+ /*
+ * Control items get realized to VPs, and
+ * copied to a temporary list, which is
+ * then copied to control if the entire
+ * line matches.
+ */
+ switch (map->op) {
+ case T_OP_EQ:
+ case T_OP_SET:
+ case T_OP_ADD:
+ fr_pair_list_init(&tmp_list);
+ if (map_to_vp(request->control_ctx, &tmp_list, request, map, NULL) < 0) {
+ fr_pair_list_free(&list);
+ RPWARN("Failed parsing check item, skipping entry");
+ match = false;
+ break;
+ }
+ LIST_VERIFY(&tmp_list);
+
+ fr_pair_list_append(&list, &tmp_list);
+ break;
+
+ /*
+ * Evaluate the map, including regexes.
+ */
+ default:
+ rcode = fr_cond_eval_map(request, map);
+ if (rcode < 0) {
+ RPWARN("Failed evaluating check item, skipping entry");
+ break;
+ }
+
+ if (rcode == 0) match = false;
break;
}
- LIST_VERIFY(&tmp_list);
- fr_pair_list_append(&list, &tmp_list);
+ if (!match) break;
}
- if (paircmp(request, &request->request_pairs, &list) != 0) {
+ if (!match) {
fr_pair_list_free(&list);
continue;
}