* which is not trivial. Or, maybe we attach it to the request somehow?
*/
+static int reparse_rcode(TALLOC_CTX *ctx, xlat_exp_t **p_arg, bool allow);
+
static fr_slen_t xlat_expr_print_unary(fr_sbuff_t *out, xlat_exp_t const *node, UNUSED void *inst, fr_sbuff_escape_rules_t const *e_rules)
{
size_t at_in = fr_sbuff_used_total(out);
FR_SBUFF_ERROR_RETURN_ADJ(&our_in, -slen);
}
+ /*
+ * Convert raw rcodes to xlat's.
+ */
+ if (reparse_rcode(head, &node, (c == '!')) < 0) {
+ talloc_free(unary);
+ FR_SBUFF_ERROR_RETURN_ADJ(&our_in, -slen);
+ }
+
xlat_func_append_arg(unary, node);
unary->flags.can_purify = (unary->call.func->flags.pure && unary->call.args->flags.pure) | unary->call.args->flags.can_purify;
return true;
}
-static int reparse_rcode(TALLOC_CTX *ctx, xlat_exp_t **p_arg)
+static int reparse_rcode(TALLOC_CTX *ctx, xlat_exp_t **p_arg, bool allow)
{
rlm_rcode_t rcode;
ssize_t slen;
return -1;
}
+ /*
+ * For unary operations.
+ *
+ * -RCODE is not allowed.
+ * ~RCODE is not allowed.
+ * !RCODE is allowed.
+ */
+ if (!allow) {
+ fr_strerror_const("Invalid operation on module return code");
+ return -1;
+ }
+
func = xlat_func_find("rcode", 5);
fr_assert(func != NULL);
/*
* Reparse module return codes if necessary.
*/
- if (logical_ops[op] && (reparse_rcode(head, &rhs) < 0)) {
+ if (logical_ops[op] && (reparse_rcode(head, &rhs, true) < 0)) {
fr_sbuff_set(&our_in, &m_rhs);
return -fr_sbuff_used(&our_in);
}
* %{rcode:handled}
*/
if (logical_ops[op]) {
- if (reparse_rcode(head, &lhs) < 0) {
+ if (reparse_rcode(head, &lhs, true) < 0) {
fr_sbuff_set(&our_in, &m_lhs);
return -fr_sbuff_used(&our_in);
}
- if (reparse_rcode(head, &rhs) < 0) {
+ if (reparse_rcode(head, &rhs, true) < 0) {
fr_sbuff_set(&our_in, &m_rhs);
return -fr_sbuff_used(&our_in);
}
/*
* Convert raw rcodes to xlat's.
*/
- if (reparse_rcode(head, &node) < 0) {
+ if (reparse_rcode(head, &node, true) < 0) {
talloc_free(head);
return 0;
}
/*
* Convert raw rcodes to xlat's.
*/
- if (reparse_rcode(head, &node) < 0) {
+ if (reparse_rcode(head, &node, true) < 0) {
talloc_free(head);
return 0;
}