bionic (5) unlang.5.gz

Provided by: freeradius-common_3.0.16+dfsg-1ubuntu3.2_all bug

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 goal of the language is to allow simple policies to be written with minimal effort.   Those  policies
       are  then  applied  when  a  request  is being processed.  Requests are processed through virtual servers
       (including the default one), in the sections titled "authorize", "authenticate", "post-auth",  "preacct",
       "accounting", "pre-proxy", "post-proxy", and "session".

       These  policies  cannot  be  used  in any other part of the configuration files, such as module or client
       configuration.

KEYWORDS

       The keywords for the language are a combination of  pre-defined  keywords,  and  references  to  loadable
       module names.  We document only the pre-defined keywords here.

       Subject  to  a  few  limitations  described  below,  any keyword can appear in any context.  The language
       consists of a series of entries, each one one line.  Each entry  begins  with  a  keyword.   Entries  are
       organized into lists.  Processing of the language is line by line, from the start of the list to the end.
       Actions are executed per-keyword.

       module-name[.section-name]
              A reference to the named module.  When processing reaches this point, the pre-compiled  module  is
              called.   The module may succeed or fail, and will return a status to "unlang" if so.  This status
              can be tested in a condition.  See the "Simple Conditions" text in  the  CONDITIONS  section,  and
              MODULE RETURN CODES, below.  If a section-name is provided, it will cause the module to execute as
              if it were listed in the named section.

                   chap  # call the CHAP module
                   sql   # call the SQL module
                   ...

       if
              Checks for a particular  condition.   If  true,  the  block  after  the  condition  is  processed.
              Otherwise,  the  block  is ignored.  See CONDITIONS, below, for documentation on the format of the
              conditions.

                   if (condition) {
                        ...
                   }

       else
              Define a block to be executed only if the previous "if" condition returned false.

                   else {
                        ...
                   }

       elsif
              Define a block to be executed only if the previous "if"  condition  returned  false,  and  if  the
              specified condition evaluates to true.

                   elsif (condition) {
                        ...
                   }

       foreach
              Loops  over  values  of  an  attribute, running the block for each value.  The return value of the
              block is the return value of the last statement executed.  The loop can be exited early  by  using
              the  "break"  keyword.   Unlike  other  languages,  "break"  here means "exit the loop at the next
              iteration", not "exit the loop now".  The result is that any statements after the "break"  keyword
              will  still  be  executed.   We  recommend  using  "break" only when it is the last statement in a
              "foreach" block.

              Inside of the "foreach" block, the attribute which is being  looped  over  can  be  referenced  as
              "Foreach-Variable-#".   Where  "#"  is  the  depth  of  the loop, starting at "0".  e.g. "Foreach-
              Variable-0".  The loops can be nested up to eight (8) deep, though this is not recommended.

                   foreach &Attribute-Reference {
                        ...
                   }

       switch
              A "switch" statement takes one argument, and contains a  series  of  "case"  statements.   When  a
              "switch" statement is encountered, the argument from the "switch" is evaluated in turn against the
              argument from each "case" statement.  The first "case" statement which matches is  executed.   All
              other  "case"  statements are ignored.  A default "case" statement can be defined, by omitting its
              argument.

              If the argument is a double quoted string (e.g. "%{exec:1 + 2}", it is expanded  as  described  in
              the  DATA  TYPES  section,  below.   The  match  is then performed on the string returned from the
              expansion.  If the argument is an  attribute  reference  (e.g.  &User-Name),  then  the  match  is
              performed  on  the  value  of  that  attribute.   Otherwise, the argument is taken to be a literal
              string, and and matching is done via simple comparison.

              No statement other than "case" can appear in a "switch" block.

                   switch <argument> {
                        ...
                   }

       case
              Provides a place-holder which matches the argument of a parent "switch" statement.

              A "case" statement cannot appear outside of a "switch" block.

              If the argument is a double quoted string (e.g. "%{exec:1 + 2}", it is expanded  as  described  in
              the  DATA  TYPES  section,  below.   The  match  is then performed on the string returned from the
              expansion.  If the argument is an  attribute  reference  (e.g.  &User-Name),  then  the  match  is
              performed  on  the  value  of  that  attribute.   Otherwise, the argument is taken to be a literal
              string, and and matching is done via simple comparison.

                   case <argument> {
                        ...
                   } A default entry can be defined by omitting the argument, as given below.  This  entry  will
              be used if no other "case" entry matches.  Only one default entry can exist in a "switch" section.

                   case {
                        ...
                   }

       update
              Update a particular attribute list, based on the attributes given in the current block.

                   update <list> {
                        &Attribute-Reference = value
                        ...
                   }  The  <list>  can  be  one  of  "request",  "reply", "proxy-request", "proxy-reply", "coa",
              "disconnect", "session-state", or "control".  As of Version 3, the <list> can be omitted, in which
              case "request" is assumed.

              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  EAP  methods with tunneled authentication sessions (i.e. PEAP and EAP-TTLS), the inner tunnel
              session can also reference "outer.request", "outer.reply", and "outer.control".  Those  references
              allow you to address the relevant list in the outer tunnel session.

              The "coa" and "disconnect" sections can only be used when the server receives an Access-Request or
              Accounting-Request.  Use "request" and "reply" instead of "coa" when the server  receives  a  CoA-
              Request or Disconnect-Request packet.

              Adding  one  or  more  attributes  to  either  of  the "coa" or "disconnect" list causes server to
              originate a CoA-Request or Disconnect-Request packet.   That  packet  is  sent  when  the  current
              Access-Request  or  Accounting-Request  has  been  finished,  and  a  reply  sent to the NAS.  See
              raddb/sites-available/originate-coa for additional information.

              The "session-state" list is primarily used for EAP.  Attributes put into the "session-state"  list
              are  saved  for  the  next  packet in the session.  They are automatically retrieved when the next
              packet is received.

              The only contents permitted in an "update" section are attributes and values.  The contents of the
              "update" section are described in the ATTRIBUTE REFERENCE and ATTRIBUTE ASSIGNMENT sections below.

       redundant
              This  section  contains  a simple list of modules.  The first module is called when the section is
              being processed.  If the first module succeeds in its operation, then the server stops  processing
              the section, and returns to the parent section.

              If, however, the module fails, then the next module in the list is tried, as described above.  The
              processing continues until one module succeeds, or until the list has been exhausted.

              Redundant sections can contain only a list of modules, and cannot contain  keywords  that  perform
              conditional operations (if, else, etc) or update an attribute list.

                   redundant {
                        sql1 # try this
                        sql2 # try this only if sql1 fails.
                        ...
                   }

       load-balance
              This section contains a simple list of modules.  When the section is entered, one module is chosen
              at random to process the request.  All of the modules in the list should be the  same  type  (e.g.
              ldap  or  sql).   All  of  the  modules in the list should behave identically, otherwise the load-
              balance section will return different results for the same request.

              Load-balance sections can contain only a list of modules, and cannot contain keywords that perform
              conditional operations (if, else, etc) or update an attribute list.

                   load-balance {
                        ldap1     # 50% of requests go here
                        ldap2     # 50% of requests go here
                   } In general, we recommend using "redundant-load-balance" instead of "load-balance".

       redundant-load-balance
              This section contains a simple list of modules.  When the section is entered, one module is chosen
              at random to process the request.  If that module succeeds, then the server stops  processing  the
              section.   If, however, the module fails, then one of the remaining modules is chosen at random to
              process the request.  This process repeats until one module succeeds, or until the list  has  been
              exhausted.

              All  of the modules in the list should be the same type (e.g. ldap or sql).  All of the modules in
              the list should behave identically, otherwise  the  load-balance  section  will  return  different
              results for the same request.

              Load-balance sections can contain only a list of modules, and cannot contain keywords that perform
              conditional operations (if, else, etc) or update an attribute list. Please see  raddb/radiusd.conf
              "instantiate" section for more configuration examples.

                   redundant-load-balance {
                        ldap1     # 50%, unless ldap2 is down, then 100%
                        ldap2     # 50%, unless ldap1 is down, then 100%
                   }

       return
              Returns  from  the current top-level section, e.g. "authorize" or "authenticate".  This keyword is
              mainly used to avoid layers of nested "if" and "else" statements.

                   authorize {
                        if (...) {
                             ...
                             return
                        }
                        ...  # this is never reached when the "if"
                        ...  # statement is executed
                   }

ATTRIBUTE REFERENCES

       Attributes may be referenced via  the  following  syntax:       &Attribute-Name       &Attribute-Name:TAG
            &Attribute-Name[NUM]       &<list>:Attribute-Name       &<list>:Attribute-Name:TAG[NUM] Where <list>
       is  one  of  "request",  "reply",  "control",   "proxy-request",   "proxy-reply",   or   "outer.request",
       "outer.reply",  "outer.control", "outer.proxy-request", or "outer.proxy-reply". just as with the "update"
       section, above.  The "<list>:" prefix is optional, and if omitted, is assumed to refer to  the  "request"
       list.

       The  TAG  portion  is a decimal integer between 1 and 31.  Please see RFC 2868 for more information about
       tags.  Tags can only be used for attributes which are marked in the dictionary as "has_tag".

       The NUM portion is used when there are multiple attributes of the same name in a list.   The  "Attribute-
       Name" reference will return the first attribute.  Using an array offset allows the policy to refer to the
       second and subsequent attributes.

       If '*' is used in the NUM portion, it evaluates to all instances of the attribute in the request.

       If 'n' is used in the NUM portion, it evaluates to the last instance of the attribute in the request.

       When an attribute name is encountered, the given list is examined for an attribute  of  the  given  name.
       Some examples are:      User-Name
            request:User-Name # same as above
            reply:User-Name
            Tunnel-Password:1
            Cisco-AVPAir[2]
            outer.request:User-Name  #  from inside of a TTLS/PEAP tunnel Note that unlike C, there is no way to
       define new attributes at run-time.  They MUST be declared in a  dictionary  file,  and  loaded  when  the
       server starts.

       All  attributes 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 attribute.  When the server receives a  packet,  it
       uses  the  packet  contents to look up entries in the dictionary, and instantiates attributes with a name
       taken from the dictionaries, and a value taken from the packet contents.  This process means that  if  an
       attribute  does  not  exist,  it  is  usually  because  it  was not contained in a packet that the server
       received.

       Once the attribute is instantiated, it is added to a list.  It can then be referenced, updated, replaced,
       etc.

CONDITIONS

       The  conditions  are  similar to C conditions in syntax, though quoted strings are supported, as with the
       Unix shell.

       Simple conditions
                   (foo) Evaluates to true if 'foo' is a non-empty string  (single  quotes,  double  quotes,  or
              back-quoted).   Also  evaluates  to true if 'foo' is a non-zero number.  Note that the language is
              poorly typed, so the string "0000" can be interpreted as a numerical  zero.   This  issue  can  be
              avoided by comparings strings to an empty string, rather than by evaluating the string by itself.

              If  the  word  'foo'  is  not  a  quoted  string,  then  it can be taken as a reference to a named
              attribute.  See "Referencing attribute lists", below, for examples of attribute  references.   The
              condition evaluates to true if the named attribute exists.

              Otherwise, if the word 'foo' is not a quoted string, and is not an attribute reference, then it is
              interpreted as a reference to a module return code.  The condition evaluates to true if  the  most
              recent  module  return  code  matches the name given here.  Valid module return codes are given in
              MODULE RETURN CODES, below.

       Negation
                   (!foo) Evaluates 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.   The  operators  ":="  and "=" are assignment operators, and are not allowed for
              comparisons.

              The operators "<", "<=", ">", and ">=" are also  allowed  for  checking  that  an  IP  address  is
              contained  within  a  network.   For  example:       if  (<ipaddr>192.0.2.1 < 192.0.2.0/24) { This
              comparison succeeds, because the address 192.0.2.1 is contained within the network 192.0.2.0/24.

       Attribute Comparisons
              When doing attribute comparisons, the data type of the attribute is used  to  determine  the  data
              type  of the right-hand side argument.       (&User-Name == "foo") Compares the value of the User-
              Name attribute to the string 'foo', and evaluates to true if the comparison holds true.

              Similarly,      (&Framed-IP-Address == 192.0.2.1) Compares  the  value  of  the  Framed-IP-Address
              attribute to the IP address 192.0.2.1.  This IP address does not need to be quoted.

       Inter-Attribute Comparisons
                   (&User-Name  ==  &Filter-Id) Compares the value of the User-Name attribute to the contents of
              the Filter-Id attribute, and evaluates to true if the comparison holds true.  Unlike the  previous
              example,  this  comparison  is  done  in a type-safe way.  For example, comparing the IP addresses
              1.2.3.4 and 127.0.0.1 as  strings  will  return  different  results  than  comparing  them  as  IP
              addresses.

              The  "&" character in the condition means that the comparison "refers" to the Filter-Id attribute.
              If left off, it means that the User-Name attribute is compared to the literal string "Filter-Id".

              Where the left-hand side is an attribute, the "&" can be omitted.   However,  it  is  allowed  for
              backwards  compatibility.   e.g.  The comparison "(&User-Name == &Filter-Id)" is equivalent to the
              example above.

              We recommend using attribute references instead of printing attributes to a  string,  e.g.  (User-
              Name == "%{Filter-Id}").  Attribute references will be faster and more efficient.

              The  conditions  will  check only the first occurrence of an attribute.  If there is more than one
              instance of an attribute, the following syntax should be used:

                   (&Attribute-Name[*] == "foo") Using the  "[*]"  syntax  means  that  it  checks  all  of  the
              instances  of  the  named  attribute.   If one attribute matches, the condition succeeds.  If none
              match, the condition fails.

       Casts       (<type>foo == bar) The left-hand-side of a condition can be "cast" to a specific  data  type.
              The data type must be one which is valid for the dictionaries.  e.g. "integer", "ipaddr", etc.

              The  comparison  is  performed  in  a type-safe way, as with "Inter-Attribute Comparisons", above.
              Both sides of the condition are parsed into temporary attributes, and the attributes compared  via
              type-specific methods.  The temporary attributes have no other effect, and are not saved anywhere.

              Casting  allows  conditions  to  perform  type-specific  comparisons.  In previous versions of the
              server, the data would have to be manually placed into an intermediate attribute (or  attributes),
              and then the attribute (or attributes) compared.  The use of a cast allows for simpler policies.

              Casts are allowed only on the left-hand side argument of a condition.

       Conditions may be nested to any depth, subject only to line length limitations (8192 bytes).

DATA TYPES

       There  are  only  a  few  data  types  supported  in the language.  Reference to attributes, numbers, and
       strings.  Any data type can appear in  stand-alone  condition,  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.

       word
              Text that is not enclosed in quotes is interpreted differently depending on where it occurs  in  a
              condition.   On  the  left  hand  side  of  a  condition,  it  is interpreted as a reference to an
              attribute.  On the right hand side, it is interpreted as a simple string, in the same manner as  a
              single-quoted string.

              Using  attribute  references  permits  limited  type-specific comparisons, as seen in the examples
              below.

                   if (&User-Name == "bob") {
                        ...
                   if (&Framed-IP-Address > 127.0.0.1) {
                        ...
                   if (&Service-Type == Login-User) {

       "strings"
              Double-quoted strings are expanded by inserting the value of any attributes (see VARIABLES, below)
              before being evaluated.  If the result is a number it is evaluated in a numerical context.

              String  length is limited by line-length, usually about 8000 characters.  A double quote character
              can be used in a string via the normal back-slash escaping method.  ("like \"this\" !")

       'strings'
              Single-quoted strings are evaluated as-is.  Their values are not expanded  as  with  double-quoted
              strings above, and they are not interpreted as attribute references.

       `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 string
              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/im
              These strings are valid only on the right-hand side of  a  comparison,  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.

              The  trailing  'm'  is  also optional, and indicates that carrot '^' and dollar '$' anchors should
              match on new lines as well as at the start and end of the subject string.

              If the comparison operator is "=~",  then  parenthesis  in  the  regular  expression  will  define
              variables containing the matching text, as described below in the VARIABLES section.

EXPANSIONS

       Attributes  are  expanded  using  the  ATTRIBUTE  REFERENCE  syntax  described above, and surrounding the
       reference with "%{...}"

            %{Attribute-Reference}

       The result will be a string which contains the  value  of  the  attribute  which  was  referenced,  as  a
       printable string.  If the attribute does not exist, the result will be an empty string.

       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 matched portion of the input string.  The variables %{1} through %{32}  will
              contain  the  substring matches, starting from the left-most capture group, onwards.  If there are
              more than 32 capture groups, the additional results will not be  accessible.   If  the  server  is
              built  with  libpcre, the results of named capture groups are available using the "%{regex:capture
              group}" expansion.  They will also be accessible using the variables described above.  Every  time
              a  regular  expression  is  evaluated, whether it matches or not, the capture group values will be
              cleared.

       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 string expansion
              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}
                     If %{Foo} has a value, returns that value.
                     Otherwise, returns literal string "bar".

              %{%{Foo}:-%{Bar}}
                     If %{Foo} has a value, returns that value.
                     Otherwise, returns the expansion of %{Bar}.

                     These   conditional   expansions   can  be  nested  to  almost  any  depth,  such  as  with
                     %{%{One}:-%{%{Two}:-%{Three}}}

       String lengths and arrays
              Similar to a Unix shell, there are ways to reference  string  lengths,  and  the  second  or  more
              instance  of an attribute in a list.  If you need more than this functionality, we suggest using a
              real language.

              %{strlen:string}
                     The number of characters in "string".  If "string" does not exist,  then  the  length  also
                     does not exist, instead of being zero.

                     The "string" is expanded before the length is taken.

              %{integer:Attribute-Name}
                     The integer value of the Attribute-Name, instead of the enumerated name.

                     e.g. If a request contains "Service-Type = Login-User", the expansion of %{integer:Service-
                     Type} will yield "1".

              %{hex:Attribute-Name}
                     The hex value of the Attribute-Name, as a series of hex digits.

                     e.g. If a request contains "Framed-IP-Address = 127.0.0.1", the expansion of  %{hex:Framed-
                     IP-Address} will yield "0x7f000001".

              %{Attribute-Name[#]}
                     The number of instances of Attribute-Name.

                     e.g.  If  a request contains "User-Name = bob", the expansion of %{User-Name[#]} will yield
                     "1".

              %{Attribute-Name[*]}
                     All values of Attribute-Name, concatenated together with ',' as the separator.

              %{List-Name:[#]}
                     The number of attributes in the named list.

              %{List-Name:[*]}
                     All values of  attributes  in  the  named-list,  concatenated  together  with  ','  as  the
                     separator. Use the %{pairs:} xlat to get a list of attributes and values.

                     e.g.  If  a response contains "Reply-Message = 'Hello', Reply-Message = 'bob' the expansion
                     of "%{reply:Reply-Message[*]} will yield "Hello\nbob"

ATTRIBUTE ASSIGNMENTS

       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-Reference = value

       Attribute Reference
              The  Attribute-Reference  must  be  a  reference (see above), using a name previously defined in a
              dictionary.  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 not 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. When the right hand  side  of  the  expression  resolves  to  multiple
                     values, it means add all values to the tail of the list.

       Enforcement and Filtering Operators
              The  following operators may also be used in addition to the ones listed above.  Their function is
              to perform enforcement or filtering on attributes in a 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.

              ==     Keep all matching attributes.  Both the attribute name and value have to match in order for
                     the attribute to remain in the list.

                     Note that this operator is very different than the '=' operator listed above!

              !=     Keep all attributes with matching name, and value not equal to the given one.

              <      Keep all attributes having values less than the value given  here.   Any  larger  value  is
                     replaced by the value given here.  If no attribute exists, it is added with the value given
                     here, as with "+=".

              <=     Keep all attributes having values less than, or equal to, the value given here.  Any larger
                     value  is  replaced  by the value given here.  If no attribute exists, it is added with the
                     value given here, as with "+=".

              >      Keep all attributes having values greater than the value given here.  Any smaller value  is
                     replaced by the value given here.  If no attribute exists, it is added with the value given
                     here, as with "+=".

              >=     Keep all attributes having values greater than, or equal to, the  value  given  here.   Any
                     smaller  value  is  replaced  by the value given here.  If no attribute exists, it is added
                     with the value given here, as with "+=".

              !*     Delete all occurrences of the named attribute, no matter what the value.

              =~     Keep all attributes having  values  which  match  the  given  regular  expression.   If  no
                     attribute matches, nothing else is done.

              !~     Keep  all attributes having values which fail to match the given regular expression.  If no
                     attribute matches, nothing else is done.

       Values
              The value can be an attribute reference, or an attribute-specific string.

              When the value is an an attribute reference, it must take  the  form  of  "&Attribute-Name".   The
              leading  "&"  signifies that the value is a reference.  The "Attribute-Name" is an attribute name,
              such as "User-Name" or "request:User-Name".  When an attribute reference is used, both  attributes
              must  have  the  same data type.  For example, "User-Name := &NAS-Port" is invalid, because "User-
              Name" is a string, and "NAS-Port" is an integer.

              We recommend using the form "Attribute-1 = &Attribute-2" for updates, instead  of  "Attribute-1  =
              "%{Attribute-2}".   The  first version will copy the attribute data, no matter what its form.  The
              second version will print the Attribute-2 to a string, and then parse it to create the  value  for
              Attribute-1.  This second version is slower and more fragile than the first one.

              When the value is an attribute-specific string, it can be a string, integer, IP address, etc.  The
              value may be expanded as  described  above  in  the  DATA  TYPES  section,  above.   For  example,
              specifying  "Framed-IP-Address = 127.0.0.1" will cause the "Framed-IP-Address" attribute to be set
              to the IP address "127.0.0.1".  However, using "Framed-IP-Address :=  module  to  be  run  with  a
              string  "127.0.0.1".   The  output  of the "echo" module will then be parsed as an IP address, and
              placed into the Framed-IP-Address attribute.

              This flexibility means that you can assign an IP address by specifying it 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.

              When string values are finally assigned to an attribute, they can have a  maximum  length  of  253
              characters.   This  limit  is due in part to both protocol and internal server requirements.  That
              is, the strings in the language can be nearly 8k in length, say for a long  SQL  query.   However,
              the output of that SQL query should be no more than 253 characters in length.

OTHER KEYWORDS

       Other  keywords in the language are taken from the names of modules loaded by the server.  These keywords
       are dependent on both the modules, and the local configuration.

       Some use keywords that are defined in the default configuration file are:

       fail   Cause the request to be treated as if a database failure had occurred.

       noop   Do nothing.  This also serves as an instruction to the configurable failover tracking that nothing
              was done in the current section.

       ok     Instructs  the  server that the request was processed properly.  This keyword can be used to over-
              ride  earlier  failures,  if  the  local  administrator  determines  that  the  faiures  are   not
              catastrophic.

       reject Causes the request to be immediately rejected

MODULE RETURN CODES

       When a module is called, it returns one of the following codes to "unlang", with the following meaning.

            notfound        information was not found
            noop            the module did nothing
            ok              the module succeeded
            updated         the module updated the request
            fail            the module failed
            reject          the module rejected the request
            userlock        the user was locked out
            invalid         the configuration was invalid
            handled         the module has handled the request itself

       These return codes can be tested for in a condition, as described above in the CONDITIONS section.

       See  also  the  file  doc/configurable_failover  for  additional methods of trapping and modifying module
       return codes.

FILES

       /etc/freeradius/3.0/radiusd.conf

SEE ALSO

       radiusd.conf(5), dictionary(5)

AUTHOR

       Alan DeKok <aland@deployingradius.com>

                                                06 December 2017                                       unlang(5)