This manual page is for Mac OS X Server version 10.6.3

If you are running Mac OS X (client), this command is not available.

If you are running a different version of Mac OS X Server, view the documentation locally:

  • In Xcode

  • In Terminal, using the man(1) command

Reading manual pages

Manual pages are intended as a quick reference for people who already understand a technology.

  • For more information about the manual page format, see the manual page for manpages(5).

  • For more information about this technology, look for other documentation in the Apple Reference Library.

  • For general information about writing shell scripts, read Shell Scripting Primer.



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-lan-guage" "un-language"
       guage" because the intention is NOT to create yet another programming language.  If  you  need  some-thing something
       thing  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  poli-cies policies
       cies are then applied when a request is being processed.

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
              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 sec-tion, section,
              tion, and MODULE RETURN CODES, below.


                   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.  Oth-erwise, Otherwise,
              erwise,  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) {
                        ...
                   }


       switch
              Evaluate  the  given string, and choose the first matching "case" statement inside of the cur-rent current
              rent block.  If the string is surrounded by double quotes, it is expanded as described in  the
              DATA TYPES section, below.

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


                   switch "string" {
                        ...
                   }


       case
              Define  a  static string to match a parent "switch" statement.  The strings given here are not
              expanded as is done with the parent "switch" statement.

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


                   case string {
                        ...
                   }


       A default entry can be defined by omitting the static string.  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 = value
                        ...
                   }


       The <list> can be one of "request", "reply", "proxy-request", "proxy-reply", or "control".  The "con-trol" "control"
       trol" 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 gener-ally generally
       ally be placed in the "control" list.

       For backwards compatibility with older versions, "check" is accepted as a synonym for "control".  The
       use of "check" is deprecated, and will be removed in a future release.

       For EAP methods with tunneled authentication sessions (i.e. PEAP and EAP-TTLS), the inner tunnel ses-sion session
       sion 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  only  contents  permitted in an "update" section are attributes and values.  The contents of the
       "update" section are described in the ATTRIBUTES section 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 pro-cessing processing
              cessing 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 per-form perform
              form 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 pro-cessing processing
              cessing the section.  If, however, the module fails, then one of the remaining modules is cho-sen chosen
              sen  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 differ-ent different
              ent 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.


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


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 (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 evalu-ates evaluates
       ates 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)


       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 simi-lar, similar,
              lar, 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 opera-tors operators
       tors are "==", "!=", "<", "<=", ">", ">=", "=~", and "!~", all with their  usual  meanings.   Invalid
       comparison operators are ":=" and "=".

       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  sup-ported. supported.
              ported.   The maximum value for a number is machine-dependent, but is usually 32-bits, includ-ing including
              ing 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  variables  (see  VARIABLES,
              below)  before being evaluated.  If the result is a number it is evaluated in a numerical con-text. context.
              text.

              String length is limited by line-length, usually about 8000 characters.  A double quote  char-acter character
              acter  (") 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 doublequoted
              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
              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 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.

              If  the  comparison  operator  is "=~", then parantheses in the regular 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  defini-tions definitions
       tions  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 dictionary, and instantiates
       variables  with a name taken from the dictionaries, 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",  "control",  "proxy-request",  "proxy-reply",  or
              "outer.request",   "outer.reply",  "outer.control",  "outer.proxy-request",  or  "outer.proxy-reply". "outer.proxyreply".
              reply". just as with the "update" section, above.  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 reference 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}
                          %{outer.reqest:User-Name} # from inside of a TTLS/PEAP tunnel


       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
              substring  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
              reference with the resulting string returned from the module.


                          %{module: string ...}


              The syntax of the string is module-specific.  Please read the module documentation  for  addi-tional additional
              tional 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 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]} %{<list>:AttributeName[index]}
                     Name[index]} may also be used.  The indexes start at zero.  This feature is NOT  avail-able available
                     able 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 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  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.

       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.

              ==     Remove  all  non-matching  attributes from the list.  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!

              <=     Enforce that the integer value of the attribute is less than  or  equal  to  the  value
                     given  here.   If  there is no attribute of the same name in the list, the attribute is
                     added with the given value, is with "+=".  If an attribute in the list exists, and  has
                     value  less  than  given  here,  it's  value is unchanged.  If an attribute in the list
                     exists, and has a value greater than given here, then that value is replaced  with  the
                     one given here.

                     This operator is valid only for attributes of integer type.

              >=     Enforce  that  the integer value of the attribute is greater than or equal to the value
                     given here.  If there is no attribute of the same name in the list,  the  attribute  is
                     added  with the given value, is with "+=".  If an attribute in the list exists, and has
                     value greater than given here, it's value is unchanged.  If an attribute  in  the  list
                     exists,  and  has  value less than given here, then that value is replaced with the one
                     given here.

                     This operator is valid only for attributes of integer type.

       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 may be expanded as described above
              in the DATA TYPES section, above.  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.

              When  string  values are finally assigned to a variable, 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  key-words keywords
       words 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  mean-ing. meaning.
       ing.


                   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.

FILES
       /etc/raddb/radiusd.conf

SEE ALSO
       radiusd.conf(5), dictionary(5)

AUTHOR
       Alan DeKok <aland@deployingradius.com>



                                                 01 Jul 2008                                       unlang(5)

Reporting Problems

The way to report a problem with this manual page depends on the type of problem:

Content errors
Report errors in the content of this documentation with the feedback links below.
Bug reports
Report bugs in the functionality of the described tool or API through Bug Reporter.
Formatting problems
Report formatting mistakes in the online version of these pages with the feedback links below.

Did this document help you? Yes It's good, but... Not helpful...