summaryrefslogtreecommitdiffstats
path: root/doc/antora/modules/unlang/pages/condition
diff options
context:
space:
mode:
Diffstat (limited to 'doc/antora/modules/unlang/pages/condition')
-rw-r--r--doc/antora/modules/unlang/pages/condition/and.adoc21
-rw-r--r--doc/antora/modules/unlang/pages/condition/cmp.adoc104
-rw-r--r--doc/antora/modules/unlang/pages/condition/eq.adoc30
-rw-r--r--doc/antora/modules/unlang/pages/condition/index.adoc85
-rw-r--r--doc/antora/modules/unlang/pages/condition/not.adoc19
-rw-r--r--doc/antora/modules/unlang/pages/condition/operands.adoc37
-rw-r--r--doc/antora/modules/unlang/pages/condition/or.adoc21
-rw-r--r--doc/antora/modules/unlang/pages/condition/para.adoc19
-rw-r--r--doc/antora/modules/unlang/pages/condition/regex.adoc180
-rw-r--r--doc/antora/modules/unlang/pages/condition/return_codes.adoc35
10 files changed, 551 insertions, 0 deletions
diff --git a/doc/antora/modules/unlang/pages/condition/and.adoc b/doc/antora/modules/unlang/pages/condition/and.adoc
new file mode 100644
index 0000000..50b3deb
--- /dev/null
+++ b/doc/antora/modules/unlang/pages/condition/and.adoc
@@ -0,0 +1,21 @@
+= The && Operator
+
+.Syntax
+[source,unlang]
+----
+(condition-1 && condition-2)
+----
+
+The `&&` operator performs a short-circuit "and" evaluation of the
+two conditions. This operator evaluates _condition-1_ and returns
+`false` if _condition-1_ returns `false`. Only if _condition-1_
+returns `true` is _condition-2_ evaluated and its result returned.
+
+.Examples
+[source,unlang]
+----
+if (&User-Name && &EAP-Message) { ...
+----
+
+// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
+// Development of this documentation was sponsored by Network RADIUS SAS.
diff --git a/doc/antora/modules/unlang/pages/condition/cmp.adoc b/doc/antora/modules/unlang/pages/condition/cmp.adoc
new file mode 100644
index 0000000..4138b86
--- /dev/null
+++ b/doc/antora/modules/unlang/pages/condition/cmp.adoc
@@ -0,0 +1,104 @@
+= Comparisons
+
+.Syntax
+[source,unlang]
+----
+lhs OP rhs
+----
+
+The most common use-case for conditions is to perform comparisons.
+The `lhs` and `rhs` of a conditional comparison can be
+xref:attr.adoc[&Attribute-Name] or xref:type/index.adoc[data]. The
+the `OP` is an operator, commonly `==` or `\<=`. It is used to
+control how the two other portions of the condition are compared.
+
+== The Comparison Operators
+
+The comparison operators are given below.
+
+[options="header"]
+|=====
+| Operator | Description
+| < | less than
+| \<= | less than or equals
+| == | equals
+| != | not equals
+| >= | greater than or equals
+| > | greater than
+| xref:condition/regex.adoc[=~] | regular expression matches
+| xref:condition/regex.adoc[!~] | regular expression does not match
+|=====
+
+The comparison operators perform _type-specific_ comparisons. The
+only exceptions are the xref:condition/regex.adoc[regular expression] operators,
+which interpret the `lhs` as a printable string, and the `rhs` as a
+regular expression.
+
+== IP Address Comparisons
+
+The type-specific comparisons operate as expected for most data types.
+The only exception is data types that are IP addresses or IP address
+prefixes. For those data types, the comparisons are done via the
+following rules:
+
+* Any unqualified IP address is assumed to have a /32 prefix (IPv4)
+ or a /128 prefix (IPv6).
+
+* If the prefixes of the left and right sides are equal, then the comparisons
+ are performed on the IP address portion.
+
+* If the prefixes of the left and right sides are not equal, then the
+ comparisons are performed as _set membership checks_.
+
+The syntax allows conditions such as `192.0.2.1 < 192.0.2/24`. This
+condition will return `true`, as the IP address `192.0.2.1' is within
+the network `192.0.2/24`.
+
+== Casting
+
+In some situations, it is useful to force the left side to be
+interpreted as a particular data type.
+
+[NOTE]
+The data types used by the cast *must* be a type taken from the RADIUS
+dictionaries, e.g., `ipaddr`, `integer`, etc. These types are not the
+same as the xref:type/index.adoc[data types] used in the
+configuration files.
+
+.Syntax
+[source,unlang]
+----
+<cast>lhs OP rhs
+----
+
+The `cast` text can be any one of the standard RADIUS dictionary data
+types, as with the following example:
+
+.Example
+[source,unlang]
+----
+<ipaddr>&Class == 127.0.0.1
+----
+
+In this example, the `Class` attribute is treated as if it was an IPv4
+address and is compared to the address `127.0.0.1`
+
+Casting is most useful when the left side of a comparison is a
+dynamically expanded string. The cast ensures that the comparison is
+done in a type-safe manner, instead of performing a string comparison.
+
+.Example
+[source,unlang]
+----
+<integer>`/bin/echo 00` == 0
+----
+
+In this example, the string output of the `echo` program is interpreted as an
+integer. It is then compared to the right side via integer
+comparisons. Since the integer `00` is equivalent to the integer `0`,
+the comparison will match. If the comparison had been performed via
+string equality checks, then the comparison would fail, because the
+strings `00` and `0` are different.
+
+// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
+// Development of this documentation was sponsored by Network RADIUS SAS.
diff --git a/doc/antora/modules/unlang/pages/condition/eq.adoc b/doc/antora/modules/unlang/pages/condition/eq.adoc
new file mode 100644
index 0000000..d9e51f3
--- /dev/null
+++ b/doc/antora/modules/unlang/pages/condition/eq.adoc
@@ -0,0 +1,30 @@
+= The == Operator
+
+.Syntax
+`(data-1 == data-2)`
+
+The `==` operator compares the result of evaluating `data-1` and
+`data-2`. As discussed in xref:type/index.adoc[Data Types], the `data-1`
+field may be interpreted as a reference to an attribute.
+
+The `data-2` field is interpreted in a type-specific manner. For
+example, if `data-1` refers to an attribute of type `ipaddr`, then
+`data-2` is evaluated as an IP address. If `data-1` refers to an
+attribute of type `integer`, then `data-2` is evaluated as an integer
+or as a named enumeration defined by a `VALUE` statement in a
+dictionary. Similarly, if `data-1` refers to an attribute of type
+`date`, then `data-2` will be interpreted as a date string.
+
+If the resulting data evaluates to be the same, then the operator
+returns `true`; otherwise, it returns `false`.
+
+.Example
+[source,unlang]
+----
+if (User-Name == "bob") {
+ ...
+}
+----
+
+// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
+// Development of this documentation was sponsored by Network RADIUS SAS.
diff --git a/doc/antora/modules/unlang/pages/condition/index.adoc b/doc/antora/modules/unlang/pages/condition/index.adoc
new file mode 100644
index 0000000..b9d9d5f
--- /dev/null
+++ b/doc/antora/modules/unlang/pages/condition/index.adoc
@@ -0,0 +1,85 @@
+= Conditional Expressions
+
+Conditions are evaluated when parsing xref:if.adoc[if] and
+xref:elsif.adoc[elsif] statements. These conditions allow the server to
+make complex decisions based on one of a number of possible criteria.
+
+.Syntax
+[source,unlang]
+----
+if ( condition ) { ...
+
+elsif ( condition ) { ...
+----
+
+Conditions are expressed using the following syntax:
+
+[options="header"]
+|=====
+| Syntax | Description
+| xref:attr.adoc[&Attribute-Name] | Check for attribute existence.
+| xref:condition/return_code.adoc[rcode] | Check return code of a previous module.
+| xref:condition/operands.adoc[data] | Check value of data.
+| xref:condition/cmp.adoc[lhs OP rhs] | Compare two kinds of data.
+| xref:condition/para.adoc[( condition )] | Check sub-condition
+| xref:condition/not.adoc[! condition] | Negate a conditional check
+| xref:condition/and.adoc[( condition ) && ...] | Check a condition AND the next one
+| xref:condition/or.adoc[( condition ) \|\| ...] | Check a condition OR the next one
+|=====
+
+
+.Examples
+[source,unlang]
+----
+if ( &User-Name == "bob" ) {
+ ...
+}
+
+if ( &Framed-IP-Address == 127.0.0.1 ) {
+ ...
+}
+
+if ( &Calling-Station-Id == "%{sql:SELECT ...}" ) {
+ ...
+}
+----
+
+== Load-time Syntax Checks
+
+The server performs a number of checks when it loads the configuration
+files. Unlike version 2, all of the conditions are syntax checked
+when the server loads. This checking greatly aids in creating
+configurations that are correct. Where the configuration is
+incorrect, a descriptive error is produced.
+
+This error contains the filename and line number of the syntax error.
+In addition, it will print out a portion of the line that caused the
+error and will point to the exact character where the error was seen.
+These descriptive messages mean that most errors are easy to find and fix.
+
+== Load-time Optimizations
+
+The server performs a number of optimizations when it loads the
+configuration files. Conditions that have static values are
+evaluated and replaced with the result of the conditional comparison.
+
+.Example
+[source,unlang]
+----
+if ( 0 == 1 ) {
+ ...
+}
+----
+
+The condition `0 == 1` is static and will evaluate to `false`. Since
+it evaluates to `false`, the configuration inside of the `if`
+statement is ignored. Any modules referenced inside of the `if`
+statement will not be loaded.
+
+This optimization is most useful for creating configurations that
+selectively load (or not) certain policies. If the condition above
+was used in version 2, then the configuration inside of the `if` statement
+would be loaded, even though it would never be used.
+
+// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
+// Development of this documentation was sponsored by Network RADIUS SAS.
diff --git a/doc/antora/modules/unlang/pages/condition/not.adoc b/doc/antora/modules/unlang/pages/condition/not.adoc
new file mode 100644
index 0000000..bde038e
--- /dev/null
+++ b/doc/antora/modules/unlang/pages/condition/not.adoc
@@ -0,0 +1,19 @@
+= The ! Operator
+
+.Syntax
+[source,unlang]
+----
+! condition
+----
+
+The `!` operator negates the result of the following condition. It
+returns `true` when _condition_ returns `false`. It returns `false`
+when _condition_ returns `true`.
+
+.Examples
+
+`(! (foo == bar))` +
+`! &User-Name`
+
+// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
+// Development of this documentation was sponsored by Network RADIUS SAS.
diff --git a/doc/antora/modules/unlang/pages/condition/operands.adoc b/doc/antora/modules/unlang/pages/condition/operands.adoc
new file mode 100644
index 0000000..4a2d00b
--- /dev/null
+++ b/doc/antora/modules/unlang/pages/condition/operands.adoc
@@ -0,0 +1,37 @@
+= Operands
+
+.Syntax
+[source,unlang]
+----
+string
+integer
+"double-quoted string"
+'single-quoted string'
+`back-quoted string`
+----
+
+Any text not matching xref:attr.adoc[&Attribute-Name] or
+xref:condition/return_code.adoc[Return Code] is interpreted as a value for a
+particular xref:type/index.adoc[data type].
+
+Double-quoted strings and back-quoted strings are dynamically expanded
+before the condition is evaluated. Single-quoted strings are static
+literals and are not dynamically expanded.
+
+When used as an existence check, the condition evaluates to `true` if
+the data is non-zero. Otherwise, the condition evaluates to `false`.
+
+For integer existence checks, `0` is `false`; all other values are `true`.
+
+For string existence checks, an empty string is `false`. All other
+strings are `true`.
+
+All other data types are disallowed in existence checks.
+
+.Examples
+
+`"hello there"` +
+`5`
+
+// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
+// Development of this documentation was sponsored by Network RADIUS SAS.
diff --git a/doc/antora/modules/unlang/pages/condition/or.adoc b/doc/antora/modules/unlang/pages/condition/or.adoc
new file mode 100644
index 0000000..80c2cb4
--- /dev/null
+++ b/doc/antora/modules/unlang/pages/condition/or.adoc
@@ -0,0 +1,21 @@
+= The || Operator
+
+.Syntax
+[source,unlang]
+----
+(expression-1 || expression-2)
+----
+
+The `||` operator performs a short-circuit "or" evaluation of the two
+expressions. This operator evaluates _condition-1_ and returns `true`
+if _condition-1_ returns true. Only if _condition-1_ returns `false`
+is _condition-2_ evaluated and its result returned.
+
+.Examples
+[source,unlang]
+----
+if (&User-Name || &NAS-IP-Address) { ...
+----
+
+// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
+// Development of this documentation was sponsored by Network RADIUS SAS.
diff --git a/doc/antora/modules/unlang/pages/condition/para.adoc b/doc/antora/modules/unlang/pages/condition/para.adoc
new file mode 100644
index 0000000..bdb3f01
--- /dev/null
+++ b/doc/antora/modules/unlang/pages/condition/para.adoc
@@ -0,0 +1,19 @@
+= The ( ) Operator
+
+.Syntax
+[source,unlang]
+----
+( condition )
+----
+
+The `( )` operator returns the result of evaluating the given
+`condition`. It is used to clarify policies or to explicitly define
+conditional precedence.
+
+.Examples
+
+`(foo)` +
+`(bar || (baz && dub))`
+
+// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
+// Development of this documentation was sponsored by Network RADIUS SAS.
diff --git a/doc/antora/modules/unlang/pages/condition/regex.adoc b/doc/antora/modules/unlang/pages/condition/regex.adoc
new file mode 100644
index 0000000..038faa6
--- /dev/null
+++ b/doc/antora/modules/unlang/pages/condition/regex.adoc
@@ -0,0 +1,180 @@
+= Regular Expressions
+
+.Syntax
+====
+[source,unlang]
+----
+(<subject> =~ /<pattern>/)
+(<subject> =~ /<pattern>/[imsux])
+
+(<subject> !~ /<pattern>/)
+(<subject> !~ /<pattern>/[imsux])
+----
+====
+
+== Matching
+The regular expression operators perform regular expression matching
+on the data. The `<subject>` field can be an attribute reference or data,
+as with the other xref:condition/cmp.adoc[comparison] operators. The `/<pattern>/`
+field must be a valid regular expression.
+
+The `=~` operator evaluates to `true` when `data` matches the
+`/<pattern>/`. Otherwise, it evaluates to `false`.
+
+The `!~` operator evaluates to `true` when `data` does not match the
+`/<pattern>/`. Otherwise, it evaluates to `true`.
+
+The regular expression comparison is performed on the _string representation_
+of the left side of the comparison. That is, if the left side is an
+xref:type/numb.adoc[integer], the regular expression will behave is if the
+value `0` was the literal string `"0"`. Similarly, if the left side is an
+xref:attr.adoc[&Attribute-Name], then the regular expression will behave is if
+the attribute was printed to a string, and the match was performed on the
+resulting string.
+
+.Checking if the `User-Name` attribute contains a realm of example.com
+====
+[source,unlang]
+----
+if (&User-Name =~ /@example\.com$/) {
+ ...
+}
+----
+====
+
+== Dialects
+
+The syntax of the regular expression is defined by the regular
+expression library available on the local system.
+
+FreeRADIUS currently supports:
+
+* link:https://www.pcre.org/original/doc/html/[libpcre] and
+link:https://www.pcre.org/current/doc/html/[libpcre2] both of which
+provide
+link:https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions[Perl
+Compatible Regular expressions].
+* Regex support provided by the local libc implementation, usually
+link:http://en.wikipedia.org/wiki/Regular_expression#POSIX_basic_and_extended[
+Posix regular expressions].
+
+[TIP]
+====
+Use the output of `radiusd -Xxv` to determine which regular expression library is in use.
+
+....
+...
+Debug : regex-pcre : no
+Debug : regex-pcre2 : yes
+Debug : regex-posix : no
+Debug : regex-posix-extended : no
+Debug : regex-binsafe : yes
+...
+Debug : pcre2 : 10.33 (2019-04-16) - retrieved at build time
+....
+====
+
+[WARNING]
+====
+Depending on the regular expression library or libc implementation the server
+was built against, the pattern matching function available may not be binary
+safe (see `regex-binsafe` in the output of `radiusd -Xxv`).
+
+If a binary safe regex match function is not available, and a match is
+attempted against a subject that contains one or more `NUL` ('\0') bytes, the
+match will be aborted, any condition that uses the result will evaluate to false,
+and a warning will be emitted.
+====
+
+== Flags
+
+The regular expression `/<pattern>/` may be followed by one or more flag
+characters. Again, which flags are available depends on the regular expression
+library the server was built with. Multiple flags may be specified per
+`/pattern/`.
+
+.Flags and their uses
+
+[options="header"]
+|=====
+| Flag Character | Available with | Effect
+| `i` | All | Enable case-insensitive matching.
+| `m` | All | '^' and '$' match newlines within the subject.
+| `s` | libpcre[2] | '.' matches anything, including newlines.
+| `u` | libpcre[2] | Treats subjects as UTF8. Invalid UTF8
+ sequences will result in the match failing.
+ |`x` | libpcre[2] | Allows comments in expressions by ignoring
+ whitespace, and text between '#' and the next
+ newline character.
+|=====
+
+== Subcapture groups
+
+When the `=~` or `!~` operators are used, then parentheses in the regular
+expression will sub capture groups, which contain part of the subject string.
+
+The special expansion `%{0}` expands to the portion of the subject that
+matched. The expansions +
+`%{1}`..`%{32}` expand to the contents of any subcapture groups.
+
+When using libpcre[2], named capture groups may also be accessed using the
+built-in expansion +
+`%{regex:<named capture group>}`.
+
+Please see the xref:xlat/builtin.adoc#_0_32[xlat documentation] for
+more information on regular expression matching.
+
+.Extracting the 'user' portion of a realm qualified string
+====
+[source,unlang]
+----
+if (&User-Name =~ /^(.*)@example\.com$/) {
+ update reply {
+ Reply-Message := "Hello %{1}"
+ }
+}
+----
+====
+
+== Pre-Compiled vs Runtime Compiled
+
+When the server starts any regular expressions comparisons it finds will be
+pre-compiled, and if support is available, JIT'd (converted to machine code)
+to ensure fast execution.
+
+If a pattern contains a xref:xlat/index.adoc[string expansion], the pattern
+cannot be compiled on startup, and will be compiled at runtime each time the
+expression is evaluated. The server will also turn off JITing for runtime
+compiled expressions, as the overhead is greater than the time that would be
+saved during evaluation.
+
+.A runtime compiled regular expression
+====
+[source,unlang]
+----
+if (&User-Name =~ /^@%{Tmp-String-0}$/) {
+ ...
+}
+----
+====
+
+To ensure optimal performance you should limit the number of patterns
+containing xref:xlat/index.adoc[string expansions], and if using PCRE, combine
+multiple expressions operating on the same subject into a single expression
+using the PCRE alternation '|' operator.
+
+.Using multiple string expansions and the PCRE alternation operator
+====
+[source,unlang]
+----
+if (&User-Name =~ /^@(%{Tmp-String-0}|%{Tmp-String-1})$/) {
+ ...
+}
+----
+====
+
+
+// Licenced under CC-by-NC 4.0.
+// Copyright (C) 2020 Network RADIUS SAS.
+// Copyright (C) 2019 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
+// Development of this documentation was sponsored by Network RADIUS SAS.
diff --git a/doc/antora/modules/unlang/pages/condition/return_codes.adoc b/doc/antora/modules/unlang/pages/condition/return_codes.adoc
new file mode 100644
index 0000000..ebc49ed
--- /dev/null
+++ b/doc/antora/modules/unlang/pages/condition/return_codes.adoc
@@ -0,0 +1,35 @@
+= The return code Operator
+
+.Syntax
+[source,unlang]
+----
+rcode
+----
+
+The Unlang interpreter tracks the return code of any module, string expansion
+or keyword that has been called.
+
+This return code can be checked in any condition. If the saved return code
+matches the `code` given here, then the condition evaluates to `true`.
+Otherwise, it evaluates to `false`.
+
+rcodes cannot be set in a condition. rcodes cannot be compared with anything else.
+
+The list of valid return codes is as follows:
+
+.Return Codes
+
+include::partial$rcode_table.adoc[]
+
+.Examples
+
+[source,unlang]
+----
+sql
+if (notfound) {
+ ...
+}
+----
+
+// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
+// Development of this documentation was sponsored by Network RADIUS SAS.