int exec_status; //!< Result of the program (if the trigger is a tmpl)
} fr_trigger_t;
-/*
- * Function to call when popping the frame
- */
-static unlang_action_t trigger_pop(UNUSED unlang_result_t *p_result, UNUSED request_t *request, UNUSED void *uctx)
-{
- return UNLANG_ACTION_CALCULATE_RESULT;
-}
-
-
/** Execute a trigger - call an executable to process an event
*
* A trigger ties a state change (e.g. connection up) in a module to an action
fr_event_list_t *el;
tmpl_rules_t t_rules;
- unlang_action_t action;
-
/*
* noop if trigger_init was never called, or if
* we're just checking the configuration.
fr_assert(trigger->vpt != NULL);
- action = unlang_function_push_with_result(unlang_interpret_result(request), /* transparent */
- request,
- NULL, /* don't call it immediately */
- trigger_pop, /* but when we pop the frame */
- NULL, ~(FR_SIGNAL_CANCEL),
- UNLANG_TOP_FRAME,
- NULL);
- if (action != UNLANG_ACTION_PUSHED_CHILD) {
- ERROR("Failed initializing the trigger");
- talloc_free(request);
- return -1;
- }
-
if (unlang_tmpl_push(trigger, &trigger->result, &trigger->out, request, trigger->vpt,
&(unlang_tmpl_args_t) {
.type = UNLANG_TMPL_ARGS_TYPE_EXEC,
.status_out = &trigger->exec_status,
.timeout = fr_time_delta_from_sec(5),
},
- }) < 0) {
+ }, UNLANG_TOP_FRAME) < 0) {
talloc_free(request);
}
if (unlang_tmpl_push(ctx, &call_env_rctx->expansion_result, &call_env_rctx->tmpl_expanded, request,
call_env_rctx->last_expanded->data.tmpl,
- NULL) < 0) return UNLANG_ACTION_FAIL;
+ NULL, UNLANG_SUB_FRAME) < 0) return UNLANG_ACTION_FAIL;
return UNLANG_ACTION_PUSHED_CHILD;
}
return 0;
case TMPL_TYPE_EXEC:
- if (unlang_tmpl_push(ctx, &out->result, &out->list, request, vpt, NULL) < 0) return -1;
+ if (unlang_tmpl_push(ctx, &out->result, &out->list, request, vpt, NULL, UNLANG_SUB_FRAME) < 0) return -1;
return 1;
case TMPL_TYPE_XLAT:
fr_value_box_list_init(&state->result);
- if (unlang_tmpl_push(state, NULL, &state->result, request, gext->vpt, NULL) < 0) return UNLANG_ACTION_FAIL;
+ if (unlang_tmpl_push(state, NULL, &state->result, request, gext->vpt, NULL, UNLANG_SUB_FRAME) < 0) return UNLANG_ACTION_FAIL;
frame_repeat(frame, unlang_limit_xlat_done);
case TMPL_TYPE_EXEC:
if (unlang_tmpl_push(update_state, NULL, &update_state->lhs_result,
request, map->lhs,
- NULL) < 0) {
+ NULL, UNLANG_SUB_FRAME) < 0) {
return UNLANG_ACTION_STOP_PROCESSING;
}
return UNLANG_ACTION_PUSHED_CHILD;
case TMPL_TYPE_EXEC:
if (unlang_tmpl_push(update_state, NULL, &update_state->rhs_result,
- request, map->rhs, NULL) < 0) {
+ request, map->rhs, NULL, UNLANG_SUB_FRAME) < 0) {
return UNLANG_ACTION_STOP_PROCESSING;
}
return UNLANG_ACTION_PUSHED_CHILD;
}
case TMPL_TYPE_EXEC:
if (unlang_tmpl_push(map_proc_state, NULL, &map_proc_state->src_result,
- request, inst->src, NULL) < 0) {
+ request, inst->src, NULL, UNLANG_SUB_FRAME) < 0) {
return UNLANG_ACTION_STOP_PROCESSING;
}
return UNLANG_ACTION_PUSHED_CHILD;
/*
* Push the xlat function
*/
- if (unlang_tmpl_push(ctx, NULL, out, request, vpt, args) < 0) return UNLANG_ACTION_FAIL;
+ if (unlang_tmpl_push(ctx, NULL, out, request, vpt, args, UNLANG_SUB_FRAME) < 0) return UNLANG_ACTION_FAIL;
return UNLANG_ACTION_PUSHED_CHILD;
}
fr_value_box_list_init(&state->result);
- if (unlang_tmpl_push(state, NULL, &state->result, request, gext->vpt, NULL) < 0) return UNLANG_ACTION_FAIL;
+ if (unlang_tmpl_push(state, NULL, &state->result, request, gext->vpt, NULL, UNLANG_SUB_FRAME) < 0) return UNLANG_ACTION_FAIL;
frame_repeat(frame, unlang_timeout_done);
* @param[in] tmpl the tmpl to expand
* @param[in] args additional controls for expanding #TMPL_TYPE_EXEC,
* and where the status of exited programs will be stored.
+ * @param[in] top_frame If true, then this is the top frame of the sub-stack.
* @return
* - 0 on success
* - -1 on failure
*/
int unlang_tmpl_push(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out, request_t *request,
- tmpl_t const *tmpl, unlang_tmpl_args_t *args)
+ tmpl_t const *tmpl, unlang_tmpl_args_t *args, bool top_frame)
{
unlang_stack_t *stack = request->stack;
unlang_stack_frame_t *frame;
* Push a new tmpl frame onto the stack
*/
if (unlang_interpret_push(p_result, request, unlang_tmpl_to_generic(ut),
- FRAME_CONF(RLM_MODULE_NOT_SET, false), UNLANG_NEXT_STOP) < 0) return -1;
+ FRAME_CONF(RLM_MODULE_NOT_SET, top_frame), UNLANG_NEXT_STOP) < 0) return -1;
frame = &stack->frame[stack->depth];
state = talloc_get_type_abort(frame->state, unlang_frame_state_tmpl_t);
typedef unlang_action_t (*fr_unlang_tmpl_resume_t)(unlang_result_t *p_result, request_t *request, void *rctx);
int unlang_tmpl_push(TALLOC_CTX *ctx, unlang_result_t *p_result, fr_value_box_list_t *out,
- request_t *request, tmpl_t const *tmpl, unlang_tmpl_args_t *args)
+ request_t *request, tmpl_t const *tmpl, unlang_tmpl_args_t *args, bool top_frame)
CC_HINT(warn_unused_result);
#ifdef __cplusplus
if (unlang_tmpl_push(ctx, NULL, &rctx->list, request, node->vpt,
TMPL_ARGS_EXEC(NULL, fr_time_delta_from_sec(EXEC_TIMEOUT),
- false, &rctx->status)) < 0) goto fail;
+ false, &rctx->status), UNLANG_SUB_FRAME) < 0) goto fail;
xa = XLAT_ACTION_PUSH_UNLANG;
goto finish;
RETURN_UNLANG_FAIL;
}
- if (unlang_tmpl_push(group_ctx, NULL, &group_ctx->expanded_filter, request, autz_ctx->call_env->group_filter, NULL) < 0) goto error;
+ if (unlang_tmpl_push(group_ctx, NULL, &group_ctx->expanded_filter, request, autz_ctx->call_env->group_filter, NULL, UNLANG_SUB_FRAME) < 0) goto error;
return UNLANG_ACTION_PUSHED_CHILD;
}
RETURN_UNLANG_FAIL;
}
- if (unlang_tmpl_push(group_ctx, NULL, &group_ctx->expanded_filter, request, group_ctx->filter_tmpl, NULL) < 0) goto error;
+ if (unlang_tmpl_push(group_ctx, NULL, &group_ctx->expanded_filter, request, group_ctx->filter_tmpl, NULL, UNLANG_SUB_FRAME) < 0) goto error;
return UNLANG_ACTION_PUSHED_CHILD;
}
if (usermod_ctx->current_mod < usermod_ctx->num_mods) {
if (unlang_module_yield(request, user_modify_mod_build_resume, NULL, 0, usermod_ctx) == UNLANG_ACTION_FAIL) RETURN_UNLANG_FAIL;
if (unlang_tmpl_push(usermod_ctx, NULL, &usermod_ctx->expanded, request,
- usermod_ctx->call_env->mod[usermod_ctx->current_mod]->tmpl, NULL) < 0) RETURN_UNLANG_FAIL;
+ usermod_ctx->call_env->mod[usermod_ctx->current_mod]->tmpl, NULL, UNLANG_SUB_FRAME) < 0) RETURN_UNLANG_FAIL;
return UNLANG_ACTION_PUSHED_CHILD;
}
if (unlang_module_yield(request, user_modify_mod_build_resume, NULL, 0, usermod_ctx) == UNLANG_ACTION_FAIL) goto fail;
;
if (unlang_tmpl_push(usermod_ctx, NULL, &usermod_ctx->expanded, request,
- usermod_ctx->call_env->mod[0]->tmpl, NULL) < 0) goto fail;
+ usermod_ctx->call_env->mod[0]->tmpl, NULL, UNLANG_SUB_FRAME) < 0) goto fail;
return UNLANG_ACTION_PUSHED_CHILD;
}
fr_value_box_list_init(&auth_ctx->cpw_ctx->local_cpw_result);
if (unlang_tmpl_push(auth_ctx, NULL, &auth_ctx->cpw_ctx->local_cpw_result, request,
- env_data->local_cpw, NULL) < 0) RETURN_UNLANG_FAIL;
+ env_data->local_cpw, NULL, UNLANG_SUB_FRAME) < 0) RETURN_UNLANG_FAIL;
break;
#else
REDEBUG("Local MS-CHAPv2 password changes require OpenSSL support");
if (env_data->ntlm_cpw_domain) {
fr_value_box_list_init(&auth_ctx->cpw_ctx->cpw_domain);
if (unlang_tmpl_push(auth_ctx, NULL, &auth_ctx->cpw_ctx->cpw_domain, request,
- env_data->ntlm_cpw_domain, NULL) < 0) RETURN_UNLANG_FAIL;
+ env_data->ntlm_cpw_domain, NULL, UNLANG_SUB_FRAME) < 0) RETURN_UNLANG_FAIL;
}
fr_value_box_list_init(&auth_ctx->cpw_ctx->cpw_user);
* b) Expanding the username
*/
if (unlang_tmpl_push(auth_ctx, NULL, &auth_ctx->cpw_ctx->cpw_user, request,
- env_data->ntlm_cpw_username, NULL) < 0) RETURN_UNLANG_FAIL;
+ env_data->ntlm_cpw_username, NULL, UNLANG_SUB_FRAME) < 0) RETURN_UNLANG_FAIL;
break;
}
fr_value_box_list_init(&xlat_ctx->query);
if (unlang_xlat_yield(request, sql_group_xlat_resume, NULL, 0, xlat_ctx) != XLAT_ACTION_YIELD) return XLAT_ACTION_FAIL;
- if (unlang_tmpl_push(xlat_ctx, NULL, &xlat_ctx->query, request, call_env->membership_query, NULL) < 0) return XLAT_ACTION_FAIL;
+ if (unlang_tmpl_push(xlat_ctx, NULL, &xlat_ctx->query, request, call_env->membership_query, NULL, UNLANG_SUB_FRAME) < 0) return XLAT_ACTION_FAIL;
return XLAT_ACTION_PUSH_UNLANG;
}
if (call_env->group_check_query) {
if (unlang_module_yield(request, mod_autz_group_resume, NULL, 0, mctx->rctx) == UNLANG_ACTION_FAIL) RETURN_UNLANG_FAIL;
if (unlang_tmpl_push(autz_ctx, NULL, &autz_ctx->query, request,
- call_env->group_check_query, NULL) < 0) RETURN_UNLANG_FAIL;
+ call_env->group_check_query, NULL, UNLANG_SUB_FRAME) < 0) RETURN_UNLANG_FAIL;
return UNLANG_ACTION_PUSHED_CHILD;
}
group_reply_push:
if (unlang_module_yield(request, mod_autz_group_resume, NULL, 0, mctx->rctx) == UNLANG_ACTION_FAIL) RETURN_UNLANG_FAIL;
if (unlang_tmpl_push(autz_ctx, NULL, &autz_ctx->query, request,
- call_env->group_reply_query, NULL) < 0) RETURN_UNLANG_FAIL;
+ call_env->group_reply_query, NULL, UNLANG_SUB_FRAME) < 0) RETURN_UNLANG_FAIL;
autz_ctx->status = autz_ctx->status & SQL_AUTZ_STAGE_GROUP ? SQL_AUTZ_GROUP_REPLY : SQL_AUTZ_PROFILE_REPLY;
return UNLANG_ACTION_PUSHED_CHILD;
}
if (!call_env->reply_query) goto skip_reply;
if (unlang_module_yield(request, mod_authorize_resume, NULL, 0, autz_ctx) == UNLANG_ACTION_FAIL) RETURN_UNLANG_FAIL;
- if (unlang_tmpl_push(autz_ctx, NULL, &autz_ctx->query, request, call_env->reply_query, NULL) < 0) RETURN_UNLANG_FAIL;
+ if (unlang_tmpl_push(autz_ctx, NULL, &autz_ctx->query, request, call_env->reply_query, NULL, UNLANG_SUB_FRAME) < 0) RETURN_UNLANG_FAIL;
autz_ctx->status = SQL_AUTZ_REPLY;
return UNLANG_ACTION_PUSHED_CHILD;
if (unlang_module_yield(request, mod_autz_group_resume, NULL, 0, autz_ctx) == UNLANG_ACTION_FAIL) RETURN_UNLANG_FAIL;
if (unlang_tmpl_push(autz_ctx, NULL, &autz_ctx->query, request,
- call_env->membership_query, NULL) < 0) RETURN_UNLANG_FAIL;
+ call_env->membership_query, NULL, UNLANG_SUB_FRAME) < 0) RETURN_UNLANG_FAIL;
autz_ctx->status = SQL_AUTZ_GROUP_MEMB;
return UNLANG_ACTION_PUSHED_CHILD;
}
* Query the check table to find any conditions associated with this user/realm/whatever...
*/
if (call_env->check_query) {
- if (unlang_tmpl_push(autz_ctx, NULL, &autz_ctx->query, request, call_env->check_query, NULL) < 0) goto error;
+ if (unlang_tmpl_push(autz_ctx, NULL, &autz_ctx->query, request, call_env->check_query, NULL, UNLANG_SUB_FRAME) < 0) goto error;
autz_ctx->status = SQL_AUTZ_CHECK;
return UNLANG_ACTION_PUSHED_CHILD;
}
if (call_env->reply_query) {
- if (unlang_tmpl_push(autz_ctx, NULL, &autz_ctx->query, request, call_env->reply_query, NULL) < 0) goto error;
+ if (unlang_tmpl_push(autz_ctx, NULL, &autz_ctx->query, request, call_env->reply_query, NULL, UNLANG_SUB_FRAME) < 0) goto error;
autz_ctx->status = SQL_AUTZ_REPLY;
return UNLANG_ACTION_PUSHED_CHILD;
}
/*
* Neither check nor reply queries were set, so we must be doing group stuff
*/
- if (unlang_tmpl_push(autz_ctx, NULL, &autz_ctx->query, request, call_env->membership_query, NULL) < 0) goto error;
+ if (unlang_tmpl_push(autz_ctx, NULL, &autz_ctx->query, request, call_env->membership_query, NULL, UNLANG_SUB_FRAME) < 0) goto error;
autz_ctx->status = SQL_AUTZ_GROUP_MEMB;
return UNLANG_ACTION_PUSHED_CHILD;
}
redundant_ctx->query_no++;
if (redundant_ctx->query_no >= talloc_array_length(call_env->query)) RETURN_UNLANG_NOOP;
if (unlang_module_yield(request, mod_sql_redundant_resume, NULL, 0, redundant_ctx) == UNLANG_ACTION_FAIL) RETURN_UNLANG_FAIL;
- if (unlang_tmpl_push(redundant_ctx, NULL, &redundant_ctx->query, request, call_env->query[redundant_ctx->query_no], NULL) < 0) RETURN_UNLANG_FAIL;
+ if (unlang_tmpl_push(redundant_ctx, NULL, &redundant_ctx->query, request, call_env->query[redundant_ctx->query_no], NULL, UNLANG_SUB_FRAME) < 0) RETURN_UNLANG_FAIL;
RDEBUG2("Trying next query...");
if (env->existing) {
alloc_ctx->status = IPPOOL_ALLOC_EXISTING;
REPEAT_MOD_ALLOC_RESUME;
- if (unlang_tmpl_push(alloc_ctx, NULL, &alloc_ctx->values, request, env->existing, NULL) < 0) {
+ if (unlang_tmpl_push(alloc_ctx, NULL, &alloc_ctx->values, request, env->existing, NULL, UNLANG_SUB_FRAME) < 0) {
error:
talloc_free(alloc_ctx);
RETURN_UNLANG_FAIL;
if (env->requested && (env->requested_address.type != FR_TYPE_NULL)) {
alloc_ctx->status = IPPOOL_ALLOC_REQUESTED;
REPEAT_MOD_ALLOC_RESUME;
- if (unlang_tmpl_push(alloc_ctx, NULL, &alloc_ctx->values, request, env->requested, NULL) < 0) goto error;
+ if (unlang_tmpl_push(alloc_ctx, NULL, &alloc_ctx->values, request, env->requested, NULL, UNLANG_SUB_FRAME) < 0) goto error;
return UNLANG_ACTION_PUSHED_CHILD;
}
goto expand_find;
*/
alloc_ctx->status = IPPOOL_ALLOC_FIND;
REPEAT_MOD_ALLOC_RESUME;
- if (unlang_tmpl_push(alloc_ctx, NULL, &alloc_ctx->values, request, env->find, NULL) < 0) goto error;
+ if (unlang_tmpl_push(alloc_ctx, NULL, &alloc_ctx->values, request, env->find, NULL, UNLANG_SUB_FRAME) < 0) goto error;
return UNLANG_ACTION_PUSHED_CHILD;
case IPPOOL_ALLOC_FIND:
if (env->pool_check) {
alloc_ctx->status = IPPOOL_ALLOC_POOL_CHECK;
REPEAT_MOD_ALLOC_RESUME;
- if (unlang_tmpl_push(alloc_ctx, NULL, &alloc_ctx->values, request, env->pool_check, NULL) < 0) goto error;
+ if (unlang_tmpl_push(alloc_ctx, NULL, &alloc_ctx->values, request, env->pool_check, NULL, UNLANG_SUB_FRAME) < 0) goto error;
return UNLANG_ACTION_PUSHED_CHILD;
}
no_address:
if (env->update) {
alloc_ctx->status = IPPOOL_ALLOC_UPDATE;
REPEAT_MOD_ALLOC_RESUME;
- if (unlang_tmpl_push(alloc_ctx, NULL, &alloc_ctx->values, request, env->update, NULL) < 0) goto error;
+ if (unlang_tmpl_push(alloc_ctx, NULL, &alloc_ctx->values, request, env->update, NULL, UNLANG_SUB_FRAME) < 0) goto error;
return UNLANG_ACTION_PUSHED_CHILD;
}