Radiator Server Documentation — v10.33.2

until

Run actions until given result occurs

Table of Contents
  • until
  • Syntax
  • Examples
  • Stop on first accept
  • Stop on ignore
  • Implement fallback behavior
  • Run actions unconditionally
  • Handle errors with when error
  • Invert results

until

Radiator pipelines run actions until an action rejects, errors, or the pipeline ends with a success or ignore. The until action can be used to modify the stop conditions within its block.

Syntax

until <stop condition> [stop conditions...] {
  # actions
} when <result condition> [result conditions...] {
  # Optional conditional actions
} else {
  # Optional actions when `when`s do not match
}

It executes the given actions until one of the actions returns a result that matches one of the given conditions and returns that result. Allowed conditions are accept, reject, ignore, and end. If no result matches, the pipeline continues until it reaches the end of the block and returns the result of the last action.

The when clause is executed when the result of the until block matches the when conditions. The allowed conditions are accept, reject, ignore, and error. Multiple conditions can be specified and the when clause itself can be defined multiple times to handle different outcomes. The else clause is executed when none of the when conditions match, but it does not capture errors.

When the when clause is defined with the error condition it captures errors that occurred in the until block. If there is no when clause with error condition, the error propagates normally. On error the aaa.caught_error variable is set to the error message and the aaa.caught_errors multivalue is extended like the try action does.

The until block cannot be configured to continue on errors directly, but the try action can be used to convert errors into ignored results.

Examples

Stop on first accept

Try all authentication methods and stop on the first successful authentication.

until accept {
  pap;
  chap;
  mschap;
  mschapv2;
  reject "No valid authentication method found";
}

Stop on ignore

Normally the pipeline does not stop if the backend call ignores. To stop on ignore too, use until reject ignore, this ensures that the pap; is not executed if the backend call ignores.

until reject ignore {
    backend {
        name "SQL_BACKEND";
        query "FIND_USER";
    }
    pap;
}

Implement fallback behavior

To implement fallback behavior use until accept reject and use try to avoid stopping on errors:

until accept reject {
    try backend {
        name "SQL_BACKEND";
        query "FIND_USER";
    }
    try backend {
        name "SQL_FALLBACK_BACKEND";
        query "FIND_USER";
    }
} when accept {
    pap;
} else {
    reject "All backends failed: %{aaa.caught_errors}"
}

This will stop when accept or reject is returned. The try is used to convert any errors to ignores, allowing the fallback backend to be executed even when the primary backend fails. We want to stop on reject because it means the primary backend is working and it did not find a user. If you want fallback on unknown users too, remove the reject condition.

Use the plural aaa.caught_errors to show all errors that occurred in the until block.

Run actions unconditionally

To always keep going use until end. Use this for side-effects that should always run but not affect the pipeline result.

until end {
    try backend {
        name "ACCOUNTING_STORE";
        query "STORE_ACCOUNTING";
    }
    try backend {
        name "ANALYTICS";
        query "SEND_ANALYTICS";
    }
    ignore;
}

Put ignore at the end to ensure it always returns with a non-rejecting result.

The end condition does not skip an erroring action. The try prefix is required to convert errors to ignores. Unhandled errors always stop the execution and propagate to calling actions or pipelines unless a when error clause handles them or explicitly converted to ignores with try.

Handle errors with when error

If the when clause has error as a condition, it is executed when the until block errors, preventing error propagation.

This allows handling of all possible outcomes of an action.

until end {
    backend {
        name "SQL_BACKEND";
        query "FIND_USER";
    }

    # Not executed if the backend errored
    debug "Backend result: %{aaa.result}";
} when accept {
    pap; # check password
} when ignore {
    reject "Backend ignored";
} when reject {
    reject "Backend rejected: %{aaa.reason}";
} when error {
    reject "Backend error: %{aaa.caught_error}";
}

The when condition can be combined to have single non-accept handling block:

until end {
    backend {
        name "SQL_BACKEND";
        query "FIND_USER";
    }
} when accept {
    pap; # check password
} when ignore reject error {
    reject "No result from the backend";
}

Invert results

To invert results so that all actions must reject for the block to accept, run actions until one accepts or ignores, then use when reject to convert the outcome. This is useful for checking if a user is not found in any known database:

until accept ignore {
    backend "EMPLOYEE_DB";
    backend "CONTRACTOR_DB";
    backend "VPN_USERS";
} when reject {
    # User not found in any database, allow guest access only
    accept;
}
Navigation
  • accept

  • all

  • any

  • append

  • assert

  • backend

  • challenge

  • chap

  • conditions

  • copy

  • count

  • debug

  • discard

  • each

  • eap

  • error

  • filter

  • first

  • hotp

  • http-basic-auth

  • if

  • ignore

  • invoke

  • log

  • map

  • message

  • modify

  • mschap

  • mschapv2

  • none

  • pap

  • reason

  • reject

  • reject_errors

  • replace

  • reply

  • rewrite

  • set

  • sleep

  • sometimes

  • stop

  • totp

  • trace

  • try

  • until

  • while

  • with

  • yubikey