Use quotes. Addresses #1288
[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 "24 November 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", "session-state", or "control".  As
195 of Version 3, the <list> can be omitted, in which case "request" is
196 assumed.
197
198 The "control" list is the list of attributes maintainted internally by
199 the server that controls how the server processes the request.  Any
200 attribute that does not go in a packet on the network will generally
201 be placed in the "control" list.
202
203 For EAP methods with tunneled authentication sessions (i.e. PEAP and
204 EAP-TTLS), the inner tunnel session can also reference
205 "outer.request", "outer.reply", and "outer.control".  Those references
206 allow you to address the relevant list in the outer tunnel session.
207
208 The "coa" and "disconnect" sections can only be used when the server
209 receives an Access-Request or Accounting-Request.  Use "request" and
210 "reply" instead of "coa" when the server receives a CoA-Request or
211 Disconnect-Request packet.
212
213 Adding one or more attributes to either of the "coa" or "disconnect"
214 list causes server to originate a CoA-Request or Disconnect-Request
215 packet.  That packet is sent when the current Access-Request or
216 Accounting-Request has been finished, and a reply sent to the NAS.
217 See raddb/sites-available/originate-coa for additional information.
218
219 The "session-state" list is primarily used for EAP.  Attributes put
220 into the "session-state" list are saved for the next packet in the
221 session.  They are automatically retreived when the next packet is
222 received.
223
224 The only contents permitted in an "update" section are attributes and
225 values.  The contents of the "update" section are described in the
226 ATTRIBUTE REFERENCE and ATTRIBUTE ASSIGNMENT sections below.
227 .IP redundant
228 This section contains a simple list of modules.  The first module is
229 called when the section is being processed.  If the first module
230 succeeds in its operation, then the server stops processing the
231 section, and returns to the parent section.
232
233 If, however, the module fails, then the next module in the list is
234 tried, as described above.  The processing continues until one module
235 succeeds, or until the list has been exhausted.
236
237 Redundant sections can contain only a list of modules, and cannot
238 contain keywords that perform conditional operations (if, else, etc)
239 or update an attribute list.
240
241 .DS
242         redundant {
243 .br
244                 sql1    # try this
245 .br
246                 sql2    # try this only if sql1 fails.
247 .br
248                 ...
249 .br
250         }
251 .DE
252 .IP load-balance
253 This section contains a simple list of modules.  When the section is
254 entered, one module is chosen at random to process the request.  All
255 of the modules in the list should be the same type (e.g. ldap or sql).
256 All of the modules in the list should behave identically, otherwise
257 the load-balance section will return different results for the same
258 request.
259
260 Load-balance sections can contain only a list of modules, and cannot
261 contain keywords that perform conditional operations (if, else, etc)
262 or update an attribute list.
263
264 .DS
265         load-balance {
266 .br
267                 ldap1   # 50% of requests go here
268 .br
269                 ldap2   # 50% of requests go here
270 .br
271         }
272 .DE
273
274 In general, we recommend using "redundant-load-balance" instead of
275 "load-balance".
276 .IP redundant-load-balance
277 This section contains a simple list of modules.  When the section is
278 entered, one module is chosen at random to process the request.  If
279 that module succeeds, then the server stops processing the section.
280 If, however, the module fails, then one of the remaining modules is
281 chosen at random to process the request.  This process repeats until
282 one module succeeds, or until the list has been exhausted.
283
284 All of the modules in the list should be the same type (e.g. ldap or
285 sql).  All of the modules in the list should behave identically,
286 otherwise the load-balance section will return different results for
287 the same request.
288
289 Load-balance sections can contain only a list of modules, and cannot
290 contain keywords that perform conditional operations (if, else, etc)
291 or update an attribute list.
292
293 .DS
294         redundant-load-balance {
295 .br
296                 ldap1   # 50%, unless ldap2 is down, then 100%
297 .br
298                 ldap2   # 50%, unless ldap1 is down, then 100%
299 .br
300         }
301 .DE
302
303 .IP return
304 .br
305 Returns from the current top-level section, e.g. "authorize" or
306 "authenticate".  This keyword is mainly used to avoid layers of nested
307 "if" and "else" statements.
308
309 .DS
310         authorize {
311 .br
312                 if (...) {
313 .br
314                         ...
315 .br
316                         return
317 .br
318                 }
319 .br
320                 ...  # this is never reached when the "if"
321 .br
322                 ...  # statement is executed
323 .br
324         }
325 .DE
326 .SH ATTRIBUTE REFERENCES
327
328 Attributes may be referenced via the following syntax:
329 .DS
330         &Attribute-Name
331         &Attribute-Name:TAG
332         &Attribute-Name[NUM]
333         &<list>:Attribute-Name
334         &<list>:Attribute-Name:TAG[NUM]
335 .DE
336 Where <list> is one of "request", "reply", "control", "proxy-request",
337 "proxy-reply", or "outer.request", "outer.reply", "outer.control",
338 "outer.proxy-request", or "outer.proxy-reply". just as with the
339 "update" section, above.  The "<list>:" prefix is optional, and if
340 omitted, is assumed to refer to the "request" list.
341
342 The TAG portion is a decimal integer between 1 and 31.  Please see RFC
343 2868 for more information about tags.  Tags can only be used for
344 attributes which are marked in the dictionary as "has_tag".
345
346 The NUM portion is used when there are multiple attributes of the same
347 name in a list.  The "Attribute-Name" reference will return the first
348 attribute.  Using an array offset allows the policy to refer to the
349 second and subsequent attributes.
350
351 If '*' is used in the NUM portion, it evaluates to all instances of
352 the attribute in the request.
353
354 If 'n' is used in the NUM portion, it evaluates to the last instance
355 of the attribute in the request.
356
357 When an attribute name is encountered, the given list is examined for
358 an attribute of the given name.  Some examples are:
359 .DS
360         User-Name
361 .br
362         request:User-Name # same as above
363 .br
364         reply:User-Name
365 .br
366         Tunnel-Password:1
367 .br
368         Cisco-AVPAir[2]
369 .br
370         outer.request:User-Name # from inside of a TTLS/PEAP tunnel
371 .DE
372 Note that unlike C, there is no way to define new attributes at
373 run-time.  They MUST be declared in a dictionary file, and loaded when
374 the server starts.
375
376 All attributes are defined in the dictionaries that accompany the
377 server.  These definitions define only the name and type, and do not
378 define the value of the attribute.  When the server receives a packet,
379 it uses the packet contents to look up entries in the dictionary, and
380 instantiates attributes with a name taken from the dictionaries, and a
381 value taken from the packet contents.  This process means that if an
382 attribute does not exist, it is usually because it was not contained
383 in a packet that the server received.
384
385 Once the attribute is instantiated, it is added to a list.  It can
386 then be referenced, updated, replaced, etc.
387
388 .SH CONDITIONS
389 The conditions are similar to C conditions in syntax, though
390 quoted strings are supported, as with the Unix shell.
391 .IP Simple
392 conditions
393 .br
394 .DS
395         (foo)
396 .DE
397
398 Evalutes to true if 'foo' is a non-empty string (single quotes, double
399 quotes, or back-quoted).  Also evaluates to true if 'foo' is a
400 non-zero number.  Note that the language is poorly typed, so the
401 string "0000" can be interpreted as a numerical zero.  This issue can
402 be avoided by comparings strings to an empty string, rather than by
403 evaluating the string by itself.
404
405 If the word 'foo' is not a quoted string, then it can be taken as a
406 reference to a named attribute.  See "Referencing attribute lists",
407 below, for examples of attribute references.  The condition evaluates
408 to true if the named attribute exists.
409
410 Otherwise, if the word 'foo' is not a quoted string, and is not an
411 attribute reference, then it is interpreted as a reference to a module
412 return code.  The condition evaluates to true if the most recent
413 module return code matches the name given here.  Valid module return
414 codes are given in MODULE RETURN CODES, below.
415 .IP Negation
416 .DS
417         (!foo)
418 .DE
419
420 Evalutes to true if 'foo' evaluates to false, and vice-versa.
421 .PP
422 Short-circuit operators
423 .RS
424 .br
425 .DS
426         (foo || bar)
427 .br
428         (foo && bar)
429 .DE
430
431 "&&" and "||" are short-circuit operators.  "&&" evaluates the first
432 condition, and evaluates the second condition if and only if the
433 result of the first condition is true.  "||" is similar, but executes
434 the second command if and only if the result of the first condition is
435 false.
436 .RE
437 .IP Comparisons
438 .DS
439         (foo == bar)
440 .DE
441
442 Compares 'foo' to 'bar', and evaluates to true if the comparison holds
443 true.  Valid comparison operators are "==", "!=", "<", "<=", ">",
444 ">=", "=~", and "!~", all with their usual meanings.  Invalid
445 comparison operators are ":=" and "=".
446 .RE
447 .IP "Attribute Comparisons"
448 .DS
449         (&User-Name == "foo")
450 .DE
451
452 Compares the value of the User-Name attribute to the string 'foo', and
453 evaluates to true if the comparison holds true.  The comparison is
454 done by printing the attribute to a string, and then doing a string
455 comparison of the two sides of the condition.
456 .RE
457 .IP "Inter-Attribute Comparisons"
458 .DS
459         (&User-Name == &Filter-Id)
460 .DE
461
462 Compares the value of the User-Name attribute to the contents of the
463 Filter-Id attribute, and evaluates to true if the comparison holds
464 true.  Unlike the previous example, this comparison is done in a
465 type-safe way.  For example, comparing the IP addresses 1.2.3.4 and
466 127.0.0.1 as strings will return different results than comparing them
467 as IP addresses.
468
469 The "&" character in the condition means that the comparison "refers"
470 to the Filter-Id attribute.  If left off, it means that the User-Name
471 attribute is compared to the literal string "Filter-Id".
472
473 Where the left-hand side is an attribute, the "&" can be omitted.
474 However, it is allowed for backwards compatibility.  e.g. The comparison
475 "(&User-Name == &Filter-Id)" is equivalent to the example above.
476
477 We recommend using attribute references instead of printing
478 attributes to a string, e.g. (User-Name == "%{Filter-Id}").
479 Attribute references will be faster and more efficient.
480
481 The conditions will check only the first occurance of an attribute.
482 If there is more than one instance of an attribute, the following
483 syntax should be used:
484
485 .DS
486         (&Attribute-Name[*] == "foo")
487 .DE
488
489 Using the "[*]" syntax means that it checks all of the instances of
490 the named attribute.  If one attribute matches, the condition
491 succeeds.  If none match, the condition fails.
492
493 .RE
494 .IP Casts
495 .DS
496         (<type>foo == bar)
497 .DE
498
499 The left-hand-side of a condition can be "cast" to a specific data
500 type.  The data type must be one which is valid for the dictionaries.
501 e.g. "integer", "ipaddr", etc.
502
503 The comparison is performed in a type-safe way, as with
504 "Inter-Attribute Comparisons", above.  Both sides of the condition are
505 parsed into temporary attributes, and the attributes compared via
506 type-specific methods.  The temporary attributes have no other effect,
507 and are not saved anywhere.
508
509 Casting allows conditions to perform type-specific comparisons.  In
510 previous versions of the server, the data would have to be manually
511 placed into an intermediate attribute (or attributes), and then the
512 attribute (or attributes) compared.  The use of a cast allows for
513 simpler policies.
514
515 Casts are allowed only on the left-hand side argument of a condition.
516 .PP
517 Conditions may be nested to any depth, subject only to line length
518 limitations (8192 bytes).
519 .SH DATA TYPES
520 There are only a few data types supported in the language.  Reference
521 to attributes, numbers, and strings.  Any data type can appear in
522 stand-alone condition, in which case they are evaluated as described
523 in "Simple conditions", above.  They can also appear (with some
524 exceptions noted below) on the left-hand or on the right-hand side of
525 a comparison.
526 .IP numbers
527 Numbers are composed of decimal digits.  Floating point, hex, and
528 octal numbers are not supported.  The maximum value for a number is
529 machine-dependent, but is usually 32-bits, including one bit for a
530 sign value.
531 .PP
532 word
533 .RS
534 Text that is not enclosed in quotes is interpreted differently
535 depending on where it occurs in a condition.  On the left hand side of
536 a condition, it is interpreted as a reference to an attribute.  On the
537 right hand side, it is interpreted as a simple string, in the same
538 manner as a single-quoted string.
539
540 Using attribute references permits limited type-specific comparisons,
541 as seen in the examples below.
542
543 .DS
544         if (&User-Name == "bob") {
545 .br
546                 ...
547 .br
548         if (&Framed-IP-Address > 127.0.0.1) {
549 .br
550                 ...
551 .br
552         if (&Service-Type == Login-User) {
553 .DE
554 .RE
555 .IP """strings"""
556 .RS
557 Double-quoted strings are expanded by inserting the value of any
558 attributes (see VARIABLES, below) before being evaluated.  If
559 the result is a number it is evaluated in a numerical context.
560
561 String length is limited by line-length, usually about 8000
562 characters.  A double quote character can be used in a string via
563 the normal back-slash escaping method.  ("like \\"this\\" !")
564 .RE
565 .IP 'strings'
566 Single-quoted strings are evaluated as-is.  Their values are not
567 expanded as with double-quoted strings above, and they are not
568 interpreted as attribute references.
569 .IP `strings`
570 Back-quoted strings are evaluated by expanding the contents of the
571 string, as described above for double-quoted strings.  The resulting
572 command given inside of the string in a sub-shell, and taking the
573 output as a string.  This behavior is much the same as that of Unix
574 shells.
575
576 Note that for security reasons, the input string is split into command
577 and arguments before string expansion is done.
578
579 For performance reasons, we suggest that the use of back-quoted
580 strings be kept to a minimum.  Executing external programs is
581 relatively expensive, and executing a large number of programs for
582 every request can quickly use all of the CPU time in a server.  If you
583 believe that you need to execute many programs, we suggest finding
584 alternative ways to achieve the same result.  In some cases, using a
585 real language may be sufficient.
586
587 .IP /regex/im
588 These strings are valid only on the right-hand side of a comparison,
589 and then only when the comparison operator is "=~" or "!~".  They are
590 regular expressions, as implemented by the local regular expression
591 library on the system.  This is usually Posix regular expressions.
592
593 The trailing 'i' is optional, and indicates that the regular
594 expression match should be done in a case-insensitive fashion.
595
596 The trailing 'm' is also optional, and indicates that carrot '^'
597 and dollar '$' anchors should match on new lines as well as at the
598 start and end of the subject string.
599
600 If the comparison operator is "=~", then parantheses in the regular
601 expression will define variables containing the matching text, as
602 described below in the VARIABLES section.
603 .SH EXPANSIONS
604 Attributes are expanded using the ATTRIBUTE REFERENCE syntax
605 described above, and surrounding the reference with "%{...}"
606
607 .DS
608         %{Attribute-Reference}
609 .DE
610
611 The result will be a string which contains the value of the attribute
612 which was referenced, as a printable string.  If the attribute does
613 not exist, the result will be an empty string.
614 .PP
615 Results of regular expression matches
616 .RS
617 If a regular expression match has previously been performed, then the
618 special variable %{0} will contain a copy of the matched portion of
619 the input string.  The variables %{1} through %{32} will contain the
620 substring matches, starting from the left-most capture group, onwards.
621 If there are more than 32 capture groups, the additional results will
622 not be accessible.
623 If the server is built with libpcre, the results of named capture groups
624 are available using the "%{regex:capture group}" expansion.  They will
625 also be accessible using the variables described above.
626 Every time a regular expression is evaluated, whether it matches or not,
627 the capture group values will be cleared.
628 .RE
629 .PP
630 Obtaining results from databases
631 .RS
632 It is useful to query a database for some information, and to use the
633 result in a condition.  The following syntax will call a module, pass
634 it the given string, and replace the string expansion with the
635 resulting string returned from the module.
636
637 .DS
638         %{module: string ...}
639 .DE
640
641 The syntax of the string is module-specific.  Please read the module
642 documentation for additional details.
643 .RE
644 .PP
645 Conditional Syntax
646 .RS
647 Conditional syntax similar to that used in Unix shells may also be
648 used.
649 .IP %{%{Foo}:-bar}
650 If %{Foo} has a value, returns that value.
651 .br
652 Otherwise, returns literal string "bar".
653 .IP %{%{Foo}:-%{Bar}}
654 If %{Foo} has a value, returns that value.
655 .br
656 Otherwise, returns the expansion of %{Bar}.
657
658 These conditional expansions can be nested to almost any depth, such
659 as with %{%{One}:-%{%{Two}:-%{Three}}}
660 .RE
661 .PP
662 String lengths and arrays
663 .RS
664 Similar to a Unix shell, there are ways to reference string lenths,
665 and the second or more instance of an attribute in a list.  If you
666 need more than this functionality, we suggest using a real language.
667 .IP %{strlen:string}
668 The number of characters in "string".  If "string" does not exist,
669 then the length also does not exist, instead of being zero.
670
671 The "string" is expanded before the length is taken.
672
673 .IP %{integer:Attribute-Name}
674 The integer value of the Attribute-Name, instead of the enumerated
675 name.
676
677 e.g. If a request contains "Service-Type = Login-User", the expansion
678 of %{integer:Service-Type} will yeild "1".
679
680 .IP %{hex:Attribute-Name}
681 The hex value of the Attribute-Name, as a series of hex digits.
682
683 e.g. If a request contains "Framed-IP-Address = 127.0.0.1", the expansion
684 of %{hex:Framed-IP-Address} will yeild "0x7f000001".
685
686 .IP %{Attribute-Name[#]}
687 The number of instances of Attribute-Name.
688
689 e.g. If a request contains "User-Name = bob", the expansion
690 of %{User-Name[#]} will yeild "1".
691
692 .IP %{Attribute-Name[*]}
693 All values of Attribute-Name, concatenated together with ',' as the
694 separator.
695
696 .IP %{List-Name:[#]}
697 The number of attributes in the named list.
698
699 .IP %{List-Name:[*]}
700 All values of attributes in the named-list, concatenated together with ','
701 as the separator. Use the %{pairs:} xlat to get a list of attributes and
702 values.
703
704 e.g. If a response contains "Reply-Message = 'Hello', Reply-Message = 'bob'
705 the expansion of "%{reply:Reply-Message[*]} will yield "Hello\\nbob"
706
707 .SH ATTRIBUTE ASSIGNMENTS
708 The attribute lists described above may be edited by listing one or
709 more attributes in an "update" section.  Once the attributes have been
710 defined, they may be referenced as described above in the VARIABLES
711 section.
712
713 The following syntax defines attributes in an "update" section.  Each
714 attribute and value has to be all on one line in the configuration
715 file.  There is no need for commas or semi-colons after the value.
716
717 .DS
718         Attribute-Reference = value
719 .DE
720 .PP
721 Attribute Reference
722 .RS
723 The Attribute-Reference must be a reference (see above), using a name
724 previously defined in a dictionary.  If an undefined name is used, the
725 server will return an error, and will not start.
726
727 .RE
728 .IP Operators
729 The operator used to assign the value of the attribute may be one of
730 the following, with the given meaning.
731 .RS
732 .IP =
733 Add the attribute to the list, if and only if an attribute of the same
734 name is not already present in that list.
735 .IP :=
736 Add the attribute to the list.  If any attribute of the same name is
737 already present in that list, its value is replaced with the value of
738 the current attribute.
739 .IP +=
740 Add the attribute to the tail of the list, even if attributes of the
741 same name are already present in the list. When the right hand side
742 of the expression resolves to multiple values, it means add all values
743 to the tail of the list.
744 .RE
745 .PP
746 Enforcement and Filtering Operators
747 .RS
748 The following operators may also be used in addition to the ones
749 listed above.  Their function is to perform enforcement or filtering
750 on attributes in a list.
751 .IP -=
752 Remove all matching attributes from the list.  Both the attribute name
753 and value have to match in order for the attribute to be removed from
754 the list.
755 .IP ==
756 Keep all matching attributes.  Both the attribute name and value have
757 to match in order for the attribute to remain in the list.
758
759 Note that this operator is very different than the '=' operator listed
760 above!
761 .IP <=
762 Keep all attributes having values less than, or equal to, the value
763 given here.  Any larger value is replaced by the value given here.  If
764 no attribute exists, it is added with the value given here, as with
765 "+=".
766
767 This operator is valid only for attributes of integer type.
768 .IP >=
769 Keep all attributes having values greater than, or equal to, the value
770 given here.  Any larger value is replaced by the value given here.  If
771 no attribute exists, it is added with the value given here, as with
772 "+=".
773
774 This operator is valid only for attributes of integer type.
775 .IP !*
776 Delete all occurances of the named attribute, no matter what the
777 value.
778 .RE
779 .IP Values
780 .br
781 The value can be an attribute reference, or an attribute-specific
782 string.
783
784 When the value is an an attribute reference, it must take the form of
785 "&Attribute-Name".  The leading "&" signifies that the value is a
786 reference.  The "Attribute-Name" is an attribute name, such as
787 "User-Name" or "request:User-Name".  When an attribute reference is
788 used, both attributes must have the same data type.  For example,
789 "User-Name := &NAS-Port" is invalid, because "User-Name" is a string,
790 and "NAS-Port" is an integer.
791
792 We recommend using the form "Attribute-1 = &Attribute-2" for updates,
793 instead of "Attribute-1 = "%{Attribute-2}".  The first version will
794 copy the attribute data, no matter what its form.  The second
795 version will print the Attribute-2 to a string, and then parse it to
796 create the value for Attribute-1.  This second version is slower
797 and more fragile than the first one.
798
799 When the value is an attribute-specific string, it can be a string,
800 integer, IP address, etc.  The value may be expanded as described
801 above in the DATA TYPES section, above.  For example, specifying
802 "Framed-IP-Address = 127.0.0.1" will cause the "Framed-IP-Address"
803 attribute to be set to the IP address "127.0.0.1".  However, using
804 "Framed-IP-Address := \"%{echo: 127.0.0.1}\"" will cause the "echo"
805 module to be run with a string "127.0.0.1".  The output of the "echo"
806 module will then be parsed as an IP address, and placed into the
807 Framed-IP-Address attribute.
808
809 This flexibility means that you can assign an IP address by specifying
810 it directly, or by having the address returned from a database query,
811 or by having the address returned as the output of a program that is
812 executed.
813
814 When string values are finally assigned to an attribute, they can have a
815 maximum length of 253 characters.  This limit is due in part to both
816 protocol and internal server requirements.  That is, the strings in
817 the language can be nearly 8k in length, say for a long SQL query.
818 However, the output of that SQL query should be no more than 253
819 characters in length.
820 .SH OTHER KEYWORDS
821 Other keywords in the language are taken from the names of modules
822 loaded by the server.  These keywords are dependent on both the
823 modules, and the local configuration.
824
825 Some use keywords that are defined in the default configuration file
826 are:
827 .IP fail
828 Cause the request to be treated as if a database failure had occurred.
829 .IP noop
830 Do nothing.  This also serves as an instruction to the configurable
831 failover tracking that nothing was done in the current section.
832 .IP ok
833 Instructs the server that the request was processed properly.  This
834 keyword can be used to over-ride earlier failures, if the local
835 administrator determines that the faiures are not catastrophic.
836 .IP reject
837 Causes the request to be immediately rejected
838 .SH MODULE RETURN CODES
839 When a module is called, it returns one of the following codes to
840 "unlang", with the following meaning.
841
842 .DS
843         notfound        information was not found
844 .br
845         noop            the module did nothing
846 .br
847         ok              the module succeeded
848 .br
849         updated         the module updated the request
850 .br
851         fail            the module failed
852 .br
853         reject          the module rejected the request
854 .br
855         userlock        the user was locked out
856 .br
857         invalid         the configuration was invalid
858 .br
859         handled         the module has handled the request itself
860 .DE
861
862 These return codes can be tested for in a condition, as described
863 above in the CONDITIONS section.
864
865 See also the file doc/configurable_failover for additional methods of
866 trapping and modifying module return codes.
867 .SH FILES
868 /etc/raddb/radiusd.conf
869 .SH "SEE ALSO"
870 .BR radiusd.conf (5),
871 .BR dictionary (5)
872 .SH AUTHOR
873 Alan DeKok <aland@deployingradius.com>