I've updated the documentation for radiusd.conf, to document the new
"un-language". Text is attached here for comment.
Alan DeKok.
--
http://deployingradius.com - The web site of the book
http://deployingradius.com/blog/ - The blog
unlang(5) FreeRADIUS Processing un-language unlang(5)
NAME
unlang - FreeRADIUS Processing un-language
DESCRIPTION
FreeRADIUS supports a simple processing language in its configuration
files. We call it an "un-language" because the intention is NOT to
create yet another programming language. If you need something more
complicated than what is described here, we suggest using the Perl or
Python modules rlm_perl, or rlm_python.
The language is similar to C in some respects, and is also similar to
Unix shell scripts in other respects. The keywords for the language
are "if", "else", "elsif", "switch", "case", and "update". Subject to
some limitations below on "switch" and "case", any keyword can appear
in any context.
KEYWORDS
if
Checks for a particular condition. If true, the block after the
condition is processed. Otherwise, the block is ignored.
if (condition) {
...
}
else
Define a block to be executed only if the previous "if" condiâ
tion returned false.
else {
...
}
elsif
Define a block to be executed only if the previous "if" condiâ
tion returned false, and if the specified condition evaluates to
true.
elsif (condition) {
...
}
switch
Evaluate the given string, and choose the first matching "case"
statement inside of the current block. No statement other than
"case" can appear in a "switch" block.
switch "string" {
...
}
case
Define a static string to match a parent "switch" statement. A
"case" statement cannot appear outside of a "switch" block.
case string {
...
}
update
Update a particular attribute list, based on the attributes
given in the current block.
update <list> {
attribute = value
...
}
The <list> can be one of "request", "reply", "proxy-request",
"proxy-reply", or "control". The "control" list is the list of
attributes maintainted internally by the server that controls
how the server processes the request. Any attribute that does
not go in a packet on the network will generally be placed in
the "control" list.
For a detailed description of the contents of the "update" secâ
tion, see the ATTRIBUTES section below.
CONDITIONS
The conditions are similar to C conditions in syntax, though quoted
strings are supported, as with the Unix shell.
Simple conditions
(foo)
Evalutes to true if âfooâ is a non-empty string, or if
âfooâ is
a non-zero number.
Negation
(!foo)
Evalutes to true if âfooâ evaluates to false, and vice-versa.
Short-circuit operators
(foo || bar)
(foo && bar)
"&&" and "||" are short-circuit operators. "&&" evaluates the
first condition, and evaluates the second condition if and only
if the result of the first condition is true. "||" is similar,
but executes the second command if and only if the result of the
first condition is false.
Comparisons
(foo == bar)
Compares âfooâ to âbarâ, and evaluates to true if the
comparison
holds true. Valid comparison operators are "==", "!=", "<",
"<=", ">", ">=", "=~", and "!~", all with their usual meanings.
Invalid comparison operators are ":=" and "=".
STRINGS AND NUMBERS
Strings and numbers can appear as stand-alone conditions, in which case
they are evaluated as described in "Simple conditions", above. They
can also appear (with some exceptions noted below) on the left-hand or
on the right-hand side of a comparison.
Numbers
Numbers are composed of decimal digits. Floating point, hex,
and octal numbers are not supported. The maximum value for a
number is machine-dependent, but is usually 32-bits, including
one bit for a sign value.
"strings"
Double-quoted strings are expanded by inserting the value of any
variables (see VARIABLES, below) before being evaluated. If the
result is a number it can be evaluated in a numerical context.
âstringsâ
Single-quoted strings are evaluated as-is.
âstringsâ
Back-quoted strings are evaluated by expanding the contents of
the string, as described above for double-quoted strings. The
resulting command given inside of the string in a sub-shell, and
taking the output as a string. This behavior is much the same
as that of Unix shells.
Note that for security reasons, the input string is split into
command and arguments before variable expansion is done.
For performance reasons, we suggest that the use of back-quoted
strings be kept to a minimum. Executing external programs is
relatively expensive, and executing a large number of programs
for every request can quickly use all of the CPU time in a
server. If you believe that you need to execute many programs,
we suggest finding alternative ways to achieve the same result.
In some cases, using a real language may be sufficient.
/regex/i
These strings are valid only on the right-hand side of a comparâ
ison, and then only when the comparison operator is "=~" or
"!~". They are regular expressions, as implemented by the local
regular expression library on the system. This is usually Posix
regular expressions.
The trailing âiâ is optional, and indicates that the
regular
expression match should be done in a case-insensitive fashion.
If the comparison operator is "=~", then parantheses in the regâ
ular expression will define variables containing the matching
text, as described below in the VARIABLES section.
VARIABLES
Run-time variables are referenced using the following syntax
%{Variable-Name}
Note that unlike C, there is no way to declare variables, or to refer
to them outside of a string context. All references to variables MUST
be contained inside of a double-quoted or back-quoted string.
Many potential variables are defined in the dictionaries that accompany
the server. These definitions define only the name and type, and do
not define the value of the variable. When the server receives a
packet, it uses the packet contents to look up entries in the dictioâ
nary, and instantiates variables with a name taken from the dictionarâ
ies, and a value taken from the packet contents. This process means
that if a variable does not exist, it is usually because it was not
mentioned in a packet that the server received.
Once the variable is instantiated, it is added to an appropriate
attribute list, as described below. In many cases, attributes and
variables are inter-changeble, and are often talked about that way.
However, variables can also refer to run-time calls to modules, which
may perform operations like SQL SELECTs, and which may return the
result as the value of the variable.
Referencing attribute lists
Attribute lists may be referenced via the following syntax
%{<list>:Attribute-Name}
Where <list> is one of "request", "reply", "proxy-request",
"proxy-reply", or "control", as described above in the documenâ
tation for the "update" section. The "<list>:" prefix is
optional, and if omitted, is assumed to refer to the "request"
list.
When a variable is encountered, the given list is examined for
an attribute of the given name. If found, the variable referâ
ence in the string is replaced with the value of that attribute.
Some examples are:
%{User-Name}
%{request:User-Name} # same as above
%{reply:User-Name}
Results of regular expression matches
If a regular expression match has previously been performed,
then the special variable %{0} will contain a copy of the input
string. The variables %{1} through %{8} will contain the subâ
string matches, starting from the left-most parantheses, and
onwards. If there are more than 8 parantheses, the additional
results will not be placed into any variables.
Obtaining results from databases
It is useful to query a database for some information, and to
use the result in a condition. The following syntax will call a
module, pass it the given string, and replace the variable refâ
erence with the resulting string returned from the module.
%{module: string ...}
The syntax of the string is module-specific. Please read the
module documentation for additional details.
Conditional Syntax
Conditional syntax similar to that used in Unix shells may also
be used.
%{Foo:-bar}
When attribute Foo is set, returns value of Foo When
attribute Foo is unset, returns literal string âbarâ
%{Foo:-%{Bar}}
When attribute Foo is set, returns value of attribute Foo
When attribute Foo is unset, returns value of attribute
Bar (if any)
%{Foo:-%{Bar:-baz}}
When attribute Foo is set, returns value of attribute Foo
When attribute Foo is unset, returns value of attribute
Bar (if any) When attribute Bar is unset, returns literal
string âbazâ
String lengths and arrays
Similar to a Unix shell, there are ways to reference string
lenths, and the second or more instance of an attribute in a
list. If you need this functionality, we recommend using a real
language.
%{#string}
The number of characters in %{string}. If %{string} is
not set, then the length is not set.
e.g. %{#Junk-junk:-foo} will yeild the string "foo".
%{Attribute-Name[index]}
Reference the Nâth occurance of the given attribute. The
syntax %{<list>:Attribute-Name[index]} may also be used.
The indexes start at zero. This feature is NOT available
for non-attribute dynamic translations, like %{sql:...}.
For example, %{User-Name[0]} is the same as %{User-Name}
The variable %{Cisco-AVPair[2]} will reference the value
of the THIRD Cisco-AVPair attribute (if it exists) in the
request packet,
%{Attribute-Name[#]}
Returns the total number of attributes of that name in
the relevant attribute list. The number will usually be
between 0 and 200.
For most requests, %{request:User-Name[#]} == 1
%{Attribute-Name[*]}
Expands to a single string, with the value of each array
member separated by a newline.
%{#Attribute-Name[index]}
Expands to the length of the string %{Attribute-
Name[index]}.
ATTRIBUTES
The attribute lists described above may be edited by listing one or
more attributes in an "update" section. Once the attributes have been
defined, they may be referenced as described above in the VARIABLES
section.
The following syntax defines attributes in an "update" section. Each
attribute and value has to be all on one line in the configuration
file. There is no need for commas or semi-colons after the value.
Attribute-Name = value
Attribute names
The Attribute-Name must be a name previously defined in a dicâ
tionary. If an undefined name is used, the server will return
an error, and will not start.
Operators
The operator used to assign the value of the attribute may be
one of the following, with the given meaning.
= Add the attribute to the list, if and only if an
attribute of the same name is already present in that
list.
:= Add the attribute to the list. If any attribute of the
same name is already present in that list, its value is
replaced with the value of the current attribute.
+= Add the attribute to the tail of the list, even if
attributes of the same name are already present in the
list.
-= Remove all matching attributes from the list. Both the
attribute name and value have to match in order for the
attribute to be removed from the list.
Values
The format of the value is attribute-specific, and is usually a
string, integer, IP address, etc. Prior to the attribute being
instantiated, the value is handled as described above in the
STRINGS AND NUMBERS section. This flexibility means that, for
example, you can assign an IP address value to an attribute by
specifying the IP address directly, or by having the address
returned from a database query, or by having the address
returned as the output of a program that is executed.
FILES
/etc/raddb/vmpsd.conf, /etc/raddb/radiusd.conf
SEE ALSO
radiusd.conf(5), vmpsd.conf(5), dictionary(5)
AUTHOR
Alan DeKok <[EMAIL PROTECTED]>
12 Jun 2007 unlang(5)
-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html