Added "return" keyword
[freeradius.git] / man / man5 / unlang.5
1 .\"     # DS - begin display
2 .de DS
3 .RS
4 .nf
5 .sp
6 ..
7 .\"     # DE - end display
8 .de DE
9 .fi
10 .RE
11 .sp
12 ..
13 .TH unlang 5 "28 October 2014" "" "FreeRADIUS Processing un-language"
14 .SH NAME
15 unlang \- FreeRADIUS Processing un\-language
16 .SH DESCRIPTION
17 FreeRADIUS supports a simple processing language in its configuration
18 files.  We call it an "un-language" because the intention is NOT to
19 create yet another programming language.  If you need something more
20 complicated than what is described here, we suggest using the Perl or
21 Python modules rlm_perl, or rlm_python.
22
23 The goal of the language is to allow simple policies to be written
24 with minimal effort.  Those policies are then applied when a request
25 is being processed.  Requests are processed through virtual servers
26 (including the default one), in the sections titled "authorize",
27 "authenticate", "post-auth", "preacct", "accounting", "pre-proxy",
28 "post-proxy", and "session".
29
30 These policies cannot be used in any other part of the configuration
31 files, such as module or client configuration.
32 .SH KEYWORDS
33 The keywords for the language are a combination of pre-defined
34 keywords, and references to loadable module names.  We document only
35 the pre-defined keywords here.
36
37 Subject to a few limitations described below, any keyword can appear
38 in any context.  The language consists of a series of entries, each
39 one one line.  Each entry begins with a keyword.  Entries are
40 organized into lists.  Processing of the language is line by line,
41 from the start of the list to the end.  Actions are executed
42 per-keyword.
43 .IP module-name
44 A reference to the named module.  When processing reaches this point,
45 the pre-compiled module is called.  The module may succeed or fail,
46 and will return a status to "unlang" if so.  This status can be tested
47 in a condition.  See the "Simple Conditions" text in the CONDITIONS
48 section, and MODULE RETURN CODES, below.
49
50 .DS
51         chap  # call the CHAP module
52 .br
53         sql   # call the SQL module
54 .br
55         ...
56 .DE
57 .IP if
58 .br
59 Checks for a particular condition.  If true, the block after the
60 condition is processed.  Otherwise, the block is ignored.  See
61 CONDITIONS, below, for documentation on the format of the conditions.
62
63 .DS
64         if (condition) {
65 .br
66                 ...
67 .br
68         }
69 .DE
70 .IP else
71 .br
72 Define a block to be executed only if the previous "if" condition
73 returned false.
74
75 .DS
76         else {
77 .br
78                 ...
79 .br
80         }
81 .DE
82 .IP elsif
83 .br
84 Define a block to be executed only if the previous "if" condition
85 returned false, and if the specified condition evaluates to true.
86
87 .DS
88         elsif (condition) {
89 .br
90                 ...
91 .br
92         }
93 .DE
94 .IP foreach
95 .br
96 Loops over values of an attribute, running the block for each value.
97 The return value of the block is the return value of the last
98 statement executed.  The loop can be exited early by using the "break"
99 keyword.  Unlike other languages, "break" here means "exit the loop at
100 the next iteration", not "exit the loop now".  The result is that any
101 statements after the "break" keyword will still be executed.  We
102 recommend using "break" only when it is the last statement in a
103 "foreach" block.
104
105 Inside of the "foreach" block, the attribute which is being looped
106 over can be referenced as "Foreach-Variable-#".  Where "#" is the
107 depth of the loop, starting at "0".  e.g. "Foreach-Variable-0".  The
108 loops can be nested up to eight (8) deep, though this is not
109 recommended.
110
111 .DS
112         foreach &Attribute-Reference {
113 .br
114                 ...
115 .br
116         }
117 .DE
118 .IP switch
119 .br
120 A "switch" statement takes one argument, and contains a series of
121 "case" statements.  When a "switch" statement is encountered, the
122 argument from the "switch" is evaluated in turn against the argument
123 from each "case" statement.  The first "case" statement which matches
124 is executed.  All other "case" statements are ignored.  A default
125 "case" statement can be defined, by omitting its argument.
126
127 If the argument is a double quoted string (e.g. "%{exec:1 + 2}", it is
128 expanded as described in the DATA TYPES section, below.  The match is
129 then performed on the string returned from the expansion.  If the
130 argument is an attribute reference (e.g. &User-Name), then the match
131 is performed on the value of that attribute.  Otherwise, the argument
132 is taken to be a literal string, and and matching is done via simple
133 comparison.
134
135 No statement other than "case" can appear in a "switch" block.
136
137 .DS
138         switch <argument> {
139 .br
140                 ...
141 .br
142         }
143 .DE
144 .IP case
145 .br
146 Provides a place-holder which matches the argument of a parent
147 "switch" statment.
148
149 A "case" statement cannot appear outside of a "switch" block.
150
151 If the argument is a double quoted string (e.g. "%{exec:1 + 2}", it is
152 expanded as described in the DATA TYPES section, below.  The match is
153 then performed on the string returned from the expansion.  If the
154 argument is an attribute reference (e.g. &User-Name), then the match
155 is performed on the value of that attribute.  Otherwise, the argument
156 is taken to be a literal string, and and matching is done via simple
157 comparison.
158
159 .DS
160         case <argument> {
161 .br
162                 ...
163 .br
164         }
165 .DE
166
167 A default entry can be defined by omitting the argument, as given
168 below.  This entry will be used if no other "case" entry matches.
169 Only one default entry can exist in a "switch" section.
170
171 .DS
172         case {
173 .br
174                 ...
175 .br
176         }
177 .DE
178 .IP update
179 .br
180 Update a particular attribute list, based on the attributes given in
181 the current block.
182
183 .DS
184         update <list> {
185 .br
186                 Attribute-Reference = value
187 .br
188                 ...
189 .br
190         }
191 .DE
192
193 The <list> can be one of "request", "reply", "proxy-request",
194 "proxy-reply", "coa", "disconnect", or "control".  As of Version 3,
195 the <list> can be omitted, in which case "request" is assumed.
196
197 The "control" list is the list of attributes maintainted internally by
198 the server that controls how the server processes the request.  Any
199 attribute that does not go in a packet on the network will generally
200 be placed in the "control" list.
201
202 For EAP methods with tunneled authentication sessions (i.e. PEAP and
203 EAP-TTLS), the inner tunnel session can also reference
204 "outer.request", "outer.reply", and "outer.control".  Those references
205 allow you to address the relevant list in the outer tunnel session.
206
207 The "coa" and "disconnect" sections can only be used when the server
208 receives an Access-Request or Accounting-Request.  Use "request" and
209 "reply" instead of "coa" when the server receives a CoA-Request or
210 Disconnect-Request packet.
211
212 Adding one or more attributes to either of the "coa" or "disconnect"
213 list causes server to originate a CoA-Request or Disconnect-Request
214 packet.  That packet is sent when the current Access-Request or
215 Accounting-Request has been finished, and a reply sent to the NAS.
216 See raddb/sites-available/originate-coa for additional information.
217
218 The only contents permitted in an "update" section are attributes and
219 values.  The contents of the "update" section are described in the
220 ATTRIBUTE REFERENCE and ATTRIBUTE ASSIGNMENT sections below.
221 .IP redundant
222 This section contains a simple list of modules.  The first module is
223 called when the section is being processed.  If the first module
224 succeeds in its operation, then the server stops processing the
225 section, and returns to the parent section.
226
227 If, however, the module fails, then the next module in the list is
228 tried, as described above.  The processing continues until one module
229 succeeds, or until the list has been exhausted.
230
231 Redundant sections can contain only a list of modules, and cannot
232 contain keywords that perform conditional operations (if, else, etc)
233 or update an attribute list.
234
235 .DS
236         redundant {
237 .br
238                 sql1    # try this
239 .br
240                 sql2    # try this only if sql1 fails.
241 .br
242                 ...
243 .br
244         }
245 .DE
246 .IP load-balance
247 This section contains a simple list of modules.  When the section is
248 entered, one module is chosen at random to process the request.  All
249 of the modules in the list should be the same type (e.g. ldap or sql).
250 All of the modules in the list should behave identically, otherwise
251 the load-balance section will return different results for the same
252 request.
253
254 Load-balance sections can contain only a list of modules, and cannot
255 contain keywords that perform conditional operations (if, else, etc)
256 or update an attribute list.
257
258 .DS
259         load-balance {
260 .br
261                 ldap1   # 50% of requests go here
262 .br
263                 ldap2   # 50% of requests go here
264 .br
265         }
266 .DE
267
268 In general, we recommend using "redundant-load-balance" instead of
269 "load-balance".
270 .IP redundant-load-balance
271 This section contains a simple list of modules.  When the section is
272 entered, one module is chosen at random to process the request.  If
273 that module succeeds, then the server stops processing the section.
274 If, however, the module fails, then one of the remaining modules is
275 chosen at random to process the request.  This process repeats until
276 one module succeeds, or until the list has been exhausted.
277
278 All of the modules in the list should be the same type (e.g. ldap or
279 sql).  All of the modules in the list should behave identically,
280 otherwise the load-balance section will return different results for
281 the same request.
282
283 Load-balance sections can contain only a list of modules, and cannot
284 contain keywords that perform conditional operations (if, else, etc)
285 or update an attribute list.
286
287 .DS
288         redundant-load-balance {
289 .br
290                 ldap1   # 50%, unless ldap2 is down, then 100%
291 .br
292                 ldap2   # 50%, unless ldap1 is down, then 100%
293 .br
294         }
295 .DE
296
297 .IP return
298 .br
299 Returns from the current top-level section, e.g. "authorize" or
300 "authenticate".  This keyword is mainly used to avoid layers of nested
301 "if" and "else" statements.
302
303 .DS
304         authorize {
305 .br
306                 if (...) {
307 .br
308                         ...
309 .br
310                         return
311 .br
312                 }
313 .br
314                 ...  # this is never reached when the "if"
315 .br
316                 ...  # statement is executed
317 .br
318         }
319 .DE
320 .SH ATTRIBUTE REFERENCES
321
322 Attributes may be referenced via the following syntax:
323 .DS
324         Attribute-Name
325         Attribute-Name:TAG
326         Attribute-Name[NUM]
327         <list>:Attribute-Name
328         <list>:Attribute-Name:TAG[NUM]
329 .DE
330 Where <list> is one of "request", "reply", "control", "proxy-request",
331 "proxy-reply", or "outer.request", "outer.reply", "outer.control",
332 "outer.proxy-request", or "outer.proxy-reply". just as with the
333 "update" section, above.  The "<list>:" prefix is optional, and if
334 omitted, is assumed to refer to the "request" list.
335
336 The TAG portion is a decimal integer between 1 and 31.  Please see RFC
337 2868 for more information about tags.  Tags can only be used for
338 attributes which are marked in the dictionary as "has_tag".
339
340 The NUM portion is used when there are multiple attributes of the same
341 name in a list.  The "Attribute-Name" reference will return the first
342 attribute.  Using an array offset allows the policy to refer to the
343 second and subsequent attributes.
344
345 When an attribute name is encountered, the given list is examined for
346 an attribute of the given name.  Some examples are:
347 .DS
348         User-Name
349 .br
350         request:User-Name # same as above
351 .br
352         reply:User-Name
353 .br
354         Tunnel-Password:1
355 .br
356         Cisco-AVPAir[2]
357 .br
358         outer.request:User-Name # from inside of a TTLS/PEAP tunnel
359 .DE
360 Note that unlike C, there is no way to define new attributes at
361 run-time.  They MUST be declared in a dictionary file, and loaded when
362 the server starts.
363
364 All attributes are defined in the dictionaries that accompany the
365 server.  These definitions define only the name and type, and do not
366 define the value of the attribute.  When the server receives a packet,
367 it uses the packet contents to look up entries in the dictionary, and
368 instantiates attributes with a name taken from the dictionaries, and a
369 value taken from the packet contents.  This process means that if an
370 attribute does not exist, it is usually because it was not contained
371 in a packet that the server received.
372
373 Once the attribute is instantiated, it is added to a list.  It can
374 then be referenced, updated, replaced, etc.
375
376 .SH CONDITIONS
377 The conditions are similar to C conditions in syntax, though
378 quoted strings are supported, as with the Unix shell.
379 .IP Simple
380 conditions
381 .br
382 .DS
383         (foo)
384 .DE
385
386 Evalutes to true if 'foo' is a non-empty string (single quotes, double
387 quotes, or back-quoted).  Also evaluates to true if 'foo' is a
388 non-zero number.  Note that the language is poorly typed, so the
389 string "0000" can be interpreted as a numerical zero.  This issue can
390 be avoided by comparings strings to an empty string, rather than by
391 evaluating the string by itself.
392
393 If the word 'foo' is not a quoted string, then it can be taken as a
394 reference to a named attribute.  See "Referencing attribute lists",
395 below, for examples of attribute references.  The condition evaluates
396 to true if the named attribute exists.
397
398 Otherwise, if the word 'foo' is not a quoted string, and is not an
399 attribute reference, then it is interpreted as a reference to a module
400 return code.  The condition evaluates to true if the most recent
401 module return code matches the name given here.  Valid module return
402 codes are given in MODULE RETURN CODES, below.
403 .IP Negation
404 .DS
405         (!foo)
406 .DE
407
408 Evalutes to true if 'foo' evaluates to false, and vice-versa.
409 .PP
410 Short-circuit operators
411 .RS
412 .br
413 .DS
414         (foo || bar)
415 .br
416         (foo && bar)
417 .DE
418
419 "&&" and "||" are short-circuit operators.  "&&" evaluates the first
420 condition, and evaluates the second condition if and only if the
421 result of the first condition is true.  "||" is similar, but executes
422 the second command if and only if the result of the first condition is
423 false.
424 .RE
425 .IP Comparisons
426 .DS
427         (foo == bar)
428 .DE
429
430 Compares 'foo' to 'bar', and evaluates to true if the comparison holds
431 true.  Valid comparison operators are "==", "!=", "<", "<=", ">",
432 ">=", "=~", and "!~", all with their usual meanings.  Invalid
433 comparison operators are ":=" and "=".
434 .RE
435 .IP Attribute Comparisons
436 .DS
437         (User-Name == "foo")
438 .DE
439
440 Compares the value of the User-Name attribute to the string 'foo', and
441 evaluates to true if the comparison holds true.  The comparison is
442 done by printing the attribute to a string, and then doing a string
443 comparison of the two sides of the condition.
444 .RE
445 .IP Inter-Attribute Comparisons
446 .DS
447         (User-Name == &Filter-Id)
448 .DE
449
450 Compares the value of the User-Name attribute to the contents of the
451 Filter-Id attribute, and evaluates to true if the comparison holds
452 true.  Unlike the previous example, this comparison is done in a
453 type-safe way.  For example, comparing the IP addresses 1.2.3.4 and
454 127.0.0.1 as strings will return different results than comparing them
455 as IP addresses.
456
457 The "&" character in the condition means that the comparison "refers"
458 to the Filter-Id attribute.  If left off, it means that the User-Name
459 attribute is compared to the literal string "Filter-Id".
460
461 Where the left-hand side is an attribute, the "&" can be omitted.
462 However, it is allowed for completeness.  e.g. The comparison
463 "(&User-Name == &Filter-Id)" is equivalent to the example above.
464
465 We recommend using attribute references instead of printing
466 attributes to a string, via (User-Name == "%{Filter-Id}").
467 Attribute references will be faster and more efficient.
468
469 .RE
470 .IP Casts
471 .DS
472         (<type>foo == bar)
473 .DE
474
475 The left-hand-side of a condition can be "cast" to a specific data
476 type.  The data type must be one which is valid for the dictionaries.
477 e.g. "integer", "ipaddr", etc.
478
479 The comparison is performed in a type-safe way, as with
480 "Inter-Attribute Comparisons", above.  Both sides of the condition are
481 parsed into temporary attributes, and the attributes compared via
482 type-specific methods.  The temporary attributes have no other effect,
483 and are not saved anywhere.
484
485 Casting allows conditions to perform type-specific comparisons.  In
486 previous versions of the server, the data would have to be manually
487 placed into an intermediate attribute (or attributes), and then the
488 attribute (or attributes) compared.  The use of a cast allows for
489 simpler policies.
490
491 Casts are allowed only on the left-hand side argument of a condition.
492 .PP
493 Conditions may be nested to any depth, subject only to line length
494 limitations (8192 bytes).
495 .SH DATA TYPES
496 There are only a few data types supported in the language.  Reference
497 to attributes, numbers, and strings.  Any data type can appear in
498 stand-alone condition, in which case they are evaluated as described
499 in "Simple conditions", above.  They can also appear (with some
500 exceptions noted below) on the left-hand or on the right-hand side of
501 a comparison.
502 .IP numbers
503 Numbers are composed of decimal digits.  Floating point, hex, and
504 octal numbers are not supported.  The maximum value for a number is
505 machine-dependent, but is usually 32-bits, including one bit for a
506 sign value.
507 .PP
508 word
509 .RS
510 Text that is not enclosed in quotes is interpreted differently
511 depending on where it occurs in a condition.  On the left hand side of
512 a condition, it is interpreted as a reference to an attribute.  On the
513 right hand side, it is interpreted as a simple string, in the same
514 manner as a single-quoted string.
515
516 Using attribute references permits limited type-specific comparisons,
517 as seen in the examples below.
518
519 .DS
520         if (User-Name == "bob") {
521 .br
522                 ...
523 .br
524         if (Framed-IP-Address > 127.0.0.1) {
525 .br
526                 ...
527 .br
528         if (Service-Type == Login-User) { 
529 .DE
530 .RE
531 .IP """strings"""
532 .RS
533 Double-quoted strings are expanded by inserting the value of any
534 attributes (see VARIABLES, below) before being evaluated.  If
535 the result is a number it is evaluated in a numerical context.
536
537 String length is limited by line-length, usually about 8000
538 characters.  A double quote character can be used in a string via
539 the normal back-slash escaping method.  ("like \\"this\\" !")
540 .RE
541 .IP 'strings'
542 Single-quoted strings are evaluated as-is.  Their values are not
543 expanded as with double-quoted strings above, and they are not
544 interpreted as attribute references.
545 .IP `strings`
546 Back-quoted strings are evaluated by expanding the contents of the
547 string, as described above for double-quoted strings.  The resulting
548 command given inside of the string in a sub-shell, and taking the
549 output as a string.  This behavior is much the same as that of Unix
550 shells.
551
552 Note that for security reasons, the input string is split into command
553 and arguments before string expansion is done.
554
555 For performance reasons, we suggest that the use of back-quoted
556 strings be kept to a minimum.  Executing external programs is
557 relatively expensive, and executing a large number of programs for
558 every request can quickly use all of the CPU time in a server.  If you
559 believe that you need to execute many programs, we suggest finding
560 alternative ways to achieve the same result.  In some cases, using a
561 real language may be sufficient.
562 .IP /regex/i
563 These strings are valid only on the right-hand side of a comparison,
564 and then only when the comparison operator is "=~" or "!~".  They are
565 regular expressions, as implemented by the local regular expression
566 library on the system.  This is usually Posix regular expressions.
567
568 The trailing 'i' is optional, and indicates that the regular
569 expression match should be done in a case-insensitive fashion.
570
571 If the comparison operator is "=~", then parantheses in the regular
572 expression will define variables containing the matching text, as
573 described below in the VARIABLES section.
574 .SH EXPANSIONS
575 Attributes are expanded using the ATTRIBUTE REFERENCE syntax
576 described above, and surrounding the reference with "%{...}"
577
578 .DS
579         %{Attribute-Reference}
580 .DE
581
582 The result will be a string which contains the value of the attribute
583 which was referenced, as a printable string.  If the attribute does
584 not exist, the result will be an empty string.
585 .PP
586 Results of regular expression matches
587 .RS
588 If a regular expression match has previously been performed, then the
589 special variable %{0} will contain a copy of the input string.  The
590 variables %{1} through %{8} will contain the substring matches,
591 starting from the left-most parantheses, and onwards.  If there are
592 more than 8 parantheses, the additional results will not be placed
593 into any variables.
594 .RE
595 .PP
596 Obtaining results from databases
597 .RS
598 It is useful to query a database for some information, and to use the
599 result in a condition.  The following syntax will call a module, pass
600 it the given string, and replace the string expansion with the
601 resulting string returned from the module.
602
603 .DS
604         %{module: string ...}
605 .DE
606
607 The syntax of the string is module-specific.  Please read the module
608 documentation for additional details.
609 .RE
610 .PP
611 Conditional Syntax
612 .RS
613 Conditional syntax similar to that used in Unix shells may also be
614 used.
615 .IP %{%{Foo}:-bar}
616 If %{Foo} has a value, returns that value.
617 .br
618 Otherwise, returns literal string "bar".
619 .IP %{%{Foo}:-%{Bar}}
620 If %{Foo} has a value, returns that value.
621 .br
622 Otherwise, returns the expansion of %{Bar}.
623
624 These conditional expansions can be nested to almost any depth, such
625 as with %{%{One}:-%{%{Two}:-%{Three}}}
626 .RE
627 .PP
628 String lengths and arrays
629 .RS
630 Similar to a Unix shell, there are ways to reference string lenths,
631 and the second or more instance of an attribute in a list.  If you
632 need more than this functionality, we suggest using a real language.
633 .IP %{strlen:string}
634 The number of characters in "string".  If "string" does not exist,
635 then the length also does not exist, instead of being zero.
636
637 The "string" is expanded before the length is taken.
638
639 .IP %{integer:Attribute-Name}
640 The integer value of the Attribute-Name, instead of the enumerated
641 name.
642
643 e.g. If a request contains "Service-Type = Login-User", the expansion
644 of %{integer:Service-Type} will yeild "1".
645
646 .IP %{hex:Attribute-Name}
647 The hex value of the Attribute-Name, as a series of hex digits.
648
649 e.g. If a request contains "Framed-IP-Address = 127.0.0.1", the expansion
650 of %{hex:Framed-IP-Address} will yeild "0x7f000001".
651
652 .SH ATTRIBUTE ASSIGNMENTS
653 The attribute lists described above may be edited by listing one or
654 more attributes in an "update" section.  Once the attributes have been
655 defined, they may be referenced as described above in the VARIABLES
656 section.
657
658 The following syntax defines attributes in an "update" section.  Each
659 attribute and value has to be all on one line in the configuration
660 file.  There is no need for commas or semi-colons after the value.
661
662 .DS
663         Attribute-Reference = value
664 .DE
665 .PP
666 Attribute Reference
667 .RS
668 The Attribute-Reference must be a reference (see above), using a name
669 previously defined in a dictionary.  If an undefined name is used, the
670 server will return an error, and will not start.
671
672 .RE
673 .IP Operators
674 The operator used to assign the value of the attribute may be one of
675 the following, with the given meaning.
676 .RS
677 .IP =
678 Add the attribute to the list, if and only if an attribute of the same
679 name is not already present in that list.
680 .IP := 
681 Add the attribute to the list.  If any attribute of the same name is
682 already present in that list, its value is replaced with the value of
683 the current attribute.
684 .IP +=
685 Add the attribute to the tail of the list, even if attributes of the
686 same name are already present in the list.
687 .RE
688 .PP
689 Enforcement and Filtering Operators
690 .RS
691 The following operators may also be used in addition to the ones
692 listed above.  Their function is to perform enforcement or filtering
693 on attributes in a list.
694 .IP -=
695 Remove all matching attributes from the list.  Both the attribute name
696 and value have to match in order for the attribute to be removed from
697 the list.
698 .IP ==
699 Keep all matching attributes.  Both the attribute name and value have
700 to match in order for the attribute to remain in the list.
701
702 Note that this operator is very different than the '=' operator listed
703 above!
704 .IP <=
705 Keep all attributes having values less than, or equal to, the value
706 given here.  Any larger value is replaced by the value given here.  If
707 no attribute exists, it is added with the value given here, as with
708 "+=".
709
710 This operator is valid only for attributes of integer type.
711 .IP >=
712 Keep all attributes having values greater than, or equal to, the value
713 given here.  Any larger value is replaced by the value given here.  If
714 no attribute exists, it is added with the value given here, as with
715 "+=".
716
717 This operator is valid only for attributes of integer type.
718 .IP !*
719 Delete all occurances of the named attribute, no matter what the
720 value.
721 .RE
722 .IP Values
723 .br
724 The value can be an attribute reference, or an attribute-specific
725 string.
726
727 When the value is an an attribute reference, it must take the form of
728 "&Attribute-Name".  The leading "&" signifies that the value is a
729 reference.  The "Attribute-Name" is an attribute name, such as
730 "User-Name" or "request:User-Name".  When an attribute reference is
731 used, both attributes must have the same data type.  For example,
732 "User-Name := &NAS-Port" is invalid, because "User-Name" is a string,
733 and "NAS-Port" is an integer.
734
735 We recommend using the form "Attribute-1 = &Attribute-2" for updates,
736 instead of "Attribute-1 = "%{Attribute-2}".  The first version will
737 copy the attribute data, no matter what its form.  The second
738 version will print the Attribute-2 to a string, and then parse it to
739 create the value for Attribute-1.  This second version is slower
740 and more fragile than the first one.
741
742 When the value is an attribute-specific string, it can be a string,
743 integer, IP address, etc.  The value may be expanded as described
744 above in the DATA TYPES section, above.  For example, specifying
745 "Framed-IP-Address = 127.0.0.1" will cause the "Framed-IP-Address"
746 attribute to be set to the IP address "127.0.0.1".  However, using
747 "Framed-IP-Address := \"%{echo: 127.0.0.1}\"" will cause the "echo"
748 module to be run with a string "127.0.0.1".  The output of the "echo"
749 module will then be parsed as an IP address, and placed into the
750 Framed-IP-Address attribute.
751
752 This flexibility means that you can assign an IP address by specifying
753 it directly, or by having the address returned from a database query,
754 or by having the address returned as the output of a program that is
755 executed.
756
757 When string values are finally assigned to an attribute, they can have a
758 maximum length of 253 characters.  This limit is due in part to both
759 protocol and internal server requirements.  That is, the strings in
760 the language can be nearly 8k in length, say for a long SQL query.
761 However, the output of that SQL query should be no more than 253
762 characters in length.
763 .SH OTHER KEYWORDS
764 Other keywords in the language are taken from the names of modules
765 loaded by the server.  These keywords are dependent on both the
766 modules, and the local configuration.
767
768 Some use keywords that are defined in the default configuration file
769 are:
770 .IP fail
771 Cause the request to be treated as if a database failure had occurred.
772 .IP noop
773 Do nothing.  This also serves as an instruction to the configurable
774 failover tracking that nothing was done in the current section.
775 .IP ok
776 Instructs the server that the request was processed properly.  This
777 keyword can be used to over-ride earlier failures, if the local
778 administrator determines that the faiures are not catastrophic.
779 .IP reject
780 Causes the request to be immediately rejected
781 .SH MODULE RETURN CODES
782 When a module is called, it returns one of the following codes to
783 "unlang", with the following meaning.
784
785 .DS
786         notfound        information was not found
787 .br
788         noop            the module did nothing
789 .br
790         ok              the module succeeded
791 .br
792         updated         the module updated the request
793 .br
794         fail            the module failed
795 .br
796         reject          the module rejected the request
797 .br
798         userlock        the user was locked out
799 .br
800         invalid         the configuration was invalid
801 .br
802         handled         the module has handled the request itself
803 .DE
804
805 These return codes can be tested for in a condition, as described
806 above in the CONDITIONS section.
807
808 See also the file doc/configurable_failover for additional methods of
809 trapping and modifying module return codes.
810 .SH FILES
811 /etc/raddb/radiusd.conf
812 .SH "SEE ALSO"
813 .BR radiusd.conf (5),
814 .BR dictionary (5)
815 .SH AUTHOR
816 Alan DeKok <aland@deployingradius.com>