From 50b37d4a27d3295a29afca2286f1a5a086142cec Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 11:49:46 +0200 Subject: Adding upstream version 3.2.1+dfsg. Signed-off-by: Daniel Baumann --- doc/antora/modules/unlang/pages/condition/and.adoc | 21 +++ doc/antora/modules/unlang/pages/condition/cmp.adoc | 104 ++++++++++++ doc/antora/modules/unlang/pages/condition/eq.adoc | 30 ++++ .../modules/unlang/pages/condition/index.adoc | 85 ++++++++++ doc/antora/modules/unlang/pages/condition/not.adoc | 19 +++ .../modules/unlang/pages/condition/operands.adoc | 37 +++++ doc/antora/modules/unlang/pages/condition/or.adoc | 21 +++ .../modules/unlang/pages/condition/para.adoc | 19 +++ .../modules/unlang/pages/condition/regex.adoc | 180 +++++++++++++++++++++ .../unlang/pages/condition/return_codes.adoc | 35 ++++ 10 files changed, 551 insertions(+) create mode 100644 doc/antora/modules/unlang/pages/condition/and.adoc create mode 100644 doc/antora/modules/unlang/pages/condition/cmp.adoc create mode 100644 doc/antora/modules/unlang/pages/condition/eq.adoc create mode 100644 doc/antora/modules/unlang/pages/condition/index.adoc create mode 100644 doc/antora/modules/unlang/pages/condition/not.adoc create mode 100644 doc/antora/modules/unlang/pages/condition/operands.adoc create mode 100644 doc/antora/modules/unlang/pages/condition/or.adoc create mode 100644 doc/antora/modules/unlang/pages/condition/para.adoc create mode 100644 doc/antora/modules/unlang/pages/condition/regex.adoc create mode 100644 doc/antora/modules/unlang/pages/condition/return_codes.adoc (limited to 'doc/antora/modules/unlang/pages/condition') 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] +---- +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] +---- +&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] +---- +`/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] +---- +( =~ //) +( =~ //[imsux]) + +( !~ //) +( !~ //[imsux]) +---- +==== + +== Matching +The regular expression operators perform regular expression matching +on the data. The `` field can be an attribute reference or data, +as with the other xref:condition/cmp.adoc[comparison] operators. The `//` +field must be a valid regular expression. + +The `=~` operator evaluates to `true` when `data` matches the +`//`. Otherwise, it evaluates to `false`. + +The `!~` operator evaluates to `true` when `data` does not match the +`//`. 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 `//` 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:}`. + +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 +// 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. -- cgit v1.2.3