From: Alan T. DeKok Date: Tue, 29 Aug 2023 21:47:14 +0000 (-0400) Subject: add %{interpreter:...} for virtual attributes X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d56b2e38f999ce0cc765fbf51fcd1e1b46666233;p=thirdparty%2Ffreeradius-server.git add %{interpreter:...} for virtual attributes Module-Return-Code Virtual-Server Request-Processing-Stage the processing stage _should_ be things like "recv Access-Request". Due to various re-architecture issues, it's now hard-coded by the src/process functions to be the name of the protocol. We probably want to fix that --- diff --git a/doc/antora/modules/reference/pages/xlat/builtin.adoc b/doc/antora/modules/reference/pages/xlat/builtin.adoc index 4f14c30a69d..df74e197bb2 100644 --- a/doc/antora/modules/reference/pages/xlat/builtin.adoc +++ b/doc/antora/modules/reference/pages/xlat/builtin.adoc @@ -246,8 +246,36 @@ It returns the raw encoded data 0x010641424344 ``` +== Interpreter State -== Server Manipulation +The state of the interpreter can be queried via the +`%{interpeter:}` expansion. The individual expansions are +documented below. + +Each expansion given here can be prefixed with one or more dot (`.`) +characters. These dots allow the expansion to refer to the current +request via a `name`, or the parent request via `.name`. If there is +no parent, the expansion returns the string ``. + +=== %{interpeter:module} + +The current module being executed. If the expansions is done in an +`unlang` statement and outside of any module, it returns the name of +the previous module which was executed. + +=== %{interpeter:processing_stage} + +Which section of a virtual server is processing the request. + +=== %{interpeter:rcode} + +The current interpreter return code, e.g. `handle`, or `ok`, etc. + +=== %{interpeter:server} + +The name of the virtual server which is running the request. + +== Server Configuration === %(config:) diff --git a/src/lib/unlang/interpret.c b/src/lib/unlang/interpret.c index b89c8fc6ce8..d8b3805d434 100644 --- a/src/lib/unlang/interpret.c +++ b/src/lib/unlang/interpret.c @@ -1451,6 +1451,7 @@ static xlat_action_t unlang_interpret_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, fr_value_box_t *vb; MEM(vb = fr_value_box_alloc_null(ctx)); + /* * Find the correct stack frame. */ @@ -1478,9 +1479,27 @@ static xlat_action_t unlang_interpret_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, * Nothing there... */ if (!instruction) { + talloc_free(vb); return XLAT_ACTION_DONE; } + /* + * How deep the current stack is. + */ + if (strcmp(fmt, "depth") == 0) { + fr_value_box_int32(vb, NULL, depth, false); + goto finish; + } + + /* + * The current module + */ + if (strcmp(fmt, "module") == 0) { + if (fr_value_box_strdup(ctx, vb, NULL, request->module, false) < 0) goto error; + + goto finish; + } + /* * Name of the instruction. */ @@ -1491,19 +1510,41 @@ static xlat_action_t unlang_interpret_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, } /* - * Unlang type. + * The request processing stage. */ - if (strcmp(fmt, "type") == 0) { - if (fr_value_box_bstrndup(ctx, vb, NULL, unlang_ops[instruction->type].name, - strlen(unlang_ops[instruction->type].name), false) < 0) goto error; + if (strcmp(fmt, "processing_stage") == 0) { + if (fr_value_box_strdup(ctx, vb, NULL, request->component, false) < 0) goto error; + goto finish; } /* - * How deep the current stack is. + * The current return code. */ - if (strcmp(fmt, "depth") == 0) { - fr_value_box_int32(vb, NULL, depth, false); + if (strcmp(fmt, "rcode") == 0) { + if (fr_value_box_strdup(ctx, vb, NULL, fr_table_str_by_value(rcode_table, request->rcode, ""), false) < 0) goto error; + + goto finish; + } + + /* + * The virtual server handling the request + */ + if (strcmp(fmt, "server") == 0) { + if (!unlang_call_current(request)) goto finish; + + if (fr_value_box_strdup(ctx, vb, NULL, cf_section_name2(unlang_call_current(request)), false) < 0) goto error; + + goto finish; + } + + /* + * Unlang instruction type. + */ + if (strcmp(fmt, "type") == 0) { + if (fr_value_box_bstrndup(ctx, vb, NULL, unlang_ops[instruction->type].name, + strlen(unlang_ops[instruction->type].name), false) < 0) goto error; + goto finish; } @@ -1512,7 +1553,8 @@ static xlat_action_t unlang_interpret_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, */ if (!instruction->ci) { if (fr_value_box_bstrndup(ctx, vb, NULL, "", 3, false) < 0) goto error; - goto finish; + + goto finish; } /* @@ -1520,6 +1562,7 @@ static xlat_action_t unlang_interpret_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, */ if (strcmp(fmt, "line") == 0) { fr_value_box_int32(vb, NULL, cf_lineno(instruction->ci), false); + goto finish; } @@ -1527,14 +1570,18 @@ static xlat_action_t unlang_interpret_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, * Filename of the current section. */ if (strcmp(fmt, "filename") == 0) { - char const *filename = cf_filename(instruction->ci); + if (fr_value_box_strdup(ctx, vb, NULL, cf_filename(instruction->ci), false) < 0) goto error; - if (fr_value_box_bstrndup(ctx, vb, NULL, filename, strlen(filename), false) < 0) goto error; goto finish; } finish: - if (vb->type != FR_TYPE_NULL) fr_dcursor_append(out, vb); + if (vb->type != FR_TYPE_NULL) { + fr_dcursor_append(out, vb); + } else { + talloc_free(vb); + } + return XLAT_ACTION_DONE; }