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