]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add %{interpreter:...} for virtual attributes
authorAlan T. DeKok <aland@freeradius.org>
Tue, 29 Aug 2023 21:47:14 +0000 (17:47 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 29 Aug 2023 22:08:53 +0000 (18:08 -0400)
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

doc/antora/modules/reference/pages/xlat/builtin.adoc
src/lib/unlang/interpret.c

index 4f14c30a69d621cc7bf48afd16e81d79e78df5a8..df74e197bb2437520c4d3580cb2d10fc7b348560 100644 (file)
@@ -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:<name>}` 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 `<underflow>`.
+
+=== %{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:<key>)
 
index b89c8fc6ce8233dfc49d9b73006a8a6e37664bc6..d8b3805d434f1766b71b9b1ba78e27ff398d7c2d 100644 (file)
@@ -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, "<INVALID>"), 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, "<INVALID>", 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;
 }