-#\r
-# Sample of a policy language.\r
-# There's no documentation other than this file.\r
-# The syntax is odd, but it works.\r
-# It's not intended for production use.\r
-# Use it if you want obscure error messages and possibly server crashes.\r
-#\r
-# $Id$\r
-#\r
-# Debugging statements\r
-#\r
-#debug print_tokens # as we're parsing this file\r
-debug print_policy # once the file has been parsed\r
-debug evaluate # print limited information during evaluation\r
-\r
-#\r
-# A named policy.\r
-#\r
-policy 3pm {\r
-if (Time-Of-Day < "15:00") {\r
- reply .= {\r
- # Use ARAP-Password for testing because it's an attribute\r
- # no one cares about.\r
- ARAP-Password = "< 15:00"\r
- }\r
-}\r
-\r
-}\r
-\r
-#\r
-# A named policy, executed during the "authorize" phase,\r
-# because it's named "authorize". \r
-#\r
-policy authorize {\r
- if (CHAP-Password) {\r
- if (!(CHAP-Challenge)) {\r
- print "Adding CHAP-Challenge = %{request:Packet-Authentication-Vector}\n"\r
-\r
- #\r
- # Append all attributes to the specified list.\r
- # The per-attribute operators MUST be '='\r
- #\r
- request .= {\r
- CHAP-Challenge = "%{request:Packet-Authentication-Vector}"\r
- }\r
- }\r
-\r
- #\r
- # Use per-attribute operators to do override, replace, etc.\r
- # It's "control", not "check items", because "check items"\r
- # is a hold-over from the "users" file, and we no longer like that.\r
- #\r
- control = {\r
- Auth-Type := CHAP\r
- }\r
- }\r
-\r
-#\r
-# This could just as well be "%{ldap: query...}" =~ ...\r
-#\r
-# if ("%{User-Name}" =~ "^(b)") {\r
-# reply .= {\r
-# Arap-Password = "Hello, %{1}"\r
-# }\r
-# }\r
-\r
- #\r
- # Execute "3pm", as if it was in-line here.\r
- #\r
-# call 3pm\r
-}\r
+#
+# Sample of a policy language for rlm_policy.
+#
+# This is NOT the "unlang" policy, and has NO RELATION to "unlang"!
+# The syntax is different, and the functionality is different.
+#
+
+# As of 2.0.0, the new configuration "un-language" is better
+# tested, has more features, and is better integrated into the
+# server than the rlm_policy module. rlm_policy is deprecated,
+# and will likely be removed in a future release.
+#
+# There is no documentation other than this file.
+#
+# The syntax is odd, but it sort of works.
+#
+# A number of sites are using it in production servers,
+# so it appears to be stable. However, we cannot answer
+# questions about it, because we use "unlang", instead of
+# this file.
+#
+# $Id$
+#
+# Debugging statements
+#
+#debug print_tokens # as we're parsing this file
+debug print_policy # once the file has been parsed
+
+# Using this requires code edits to rlm_policy/evaluate.c
+#debug evaluate # print limited information during evaluation
+
+#
+# A named policy.
+#
+policy 3pm {
+if (Time-Of-Day < "15:00") {
+ #
+ # The general form of edits to the attribute lists:
+ #
+ # name s-operator {
+ # Attribute-Name = Value
+ # }
+ #
+ # name is: request, reply, control, proxy-request, proxy-reply
+ #
+ # s-operator is operator for section, not attributes:
+ #
+ # = append, using operators from attributes
+ # .= append attributes, ignoring operators from attributes
+ # ^= add to head of list
+ # ^== add BEFORE matching attribute
+ # ^. append
+ # ^.= append BEFORE matching attribute
+ # $= add AFTER (same as =)
+ # $== add AFTER matching attribute
+ # $. add after (same as .=)
+ # $.= add after matching
+ #
+ # If the above explanation confuses you, don't ask. Try various
+ # configurations to see what happens. The results are difficult
+ # to explain, but easy to understand once you see them in action.
+ #
+ # The "matching attribute" text above refers to the syntax:
+ #
+ # name s-operator (match) {
+ # Attribute-Name = Value
+ # }
+ #
+ # Where "match" is something like: User-Name == "bob"
+ #
+ # This lets you insert/edit/update attributes by selected
+ # position, which can be useful.
+ #
+ reply .= {
+ # Use ARAP-Password for testing because it's an attribute
+ # no one cares about.
+ ARAP-Password = "< 15:00"
+ }
+}
+
+}
+
+#
+# A named policy, executed during the "authorize" phase,
+# because it's named "authorize".
+#
+policy authorize {
+ if (CHAP-Password) {
+ if (!CHAP-Challenge) {
+ print "Adding CHAP-Challenge = %{request:Packet-Authentication-Vector}\n"
+
+ #
+ # Append all attributes to the specified list.
+ # The per-attribute operators MUST be '='
+ #
+ request .= {
+ CHAP-Challenge = "%{request:Packet-Authentication-Vector}"
+ }
+ }
+
+ #
+ # Use per-attribute operators to do override, replace, etc.
+ # It's "control", not "check items", because "check items"
+ # is a hold-over from the "users" file, and we no longer like that.
+ #
+ control = {
+ Auth-Type := CHAP
+ }
+ }
+
+#
+# This could just as well be "%{ldap: query...}" =~ ...
+#
+# if ("%{User-Name}" =~ "^(b)") {
+# reply .= {
+# Arap-Password = "Hello, %{1}"
+# }
+# }
+
+ #
+ # Execute "3pm", as if it was in-line here.
+ #
+# call 3pm
+}
+
+######################################################################
+#
+# The following entries are for example purposes only.
+#
+
+# Insert the attribute at the top of the list.
+#
+#reply ^= {
+# Attribute1 += "Value1"
+#}
+
+
+# Insert attribute1 before Attribute2 if found, otherwise it behaves
+# like ^=
+#reply ^== ( Attribute2 == "Value2" ) {
+# Attribute1 += "Value1"
+#}
+
+# ^. and ^.= have the same difference as .= and =
+# namely they append the attribute list instead of looking at the
+# attribute operators.
+#
+# Otherwise they are the same.
+
+# Motivation:
+#
+# Cisco NAS's will kick users who assign a VRF after assigning an IP
+# address. The VRF must come first.
+#
+# A sample policy to fix this is:
+#
+policy add_inter_vrf {
+ #
+ # If there's a matching lcp:...,
+ # then add the vrf entry before it.
+ #
+ reply ^== ( reply:Cisco-Avpair =~ "lcp:interface-config") {
+ Cisco-Avpair += "lcp:interface-config=ip vrf forwarding CHL-PRIVATE"
+ }
+
+ #
+ # If there's no ip address thingy,
+ # add ip unnumbered after the vrf stuff.
+ #
+ if (!reply:Cisco-Avpair =~ "lcp:interface-config=ip address.*") {
+ reply $== (reply:Cisco-AVpair == "lcp:interface-config=ip vrf forwarding CHL-PRIVATE") {
+ Cisco-Avpair += "lcp:interface-config=ip unnumbered l10"
+ }
+ }
+
+ #
+ # No IP address assigned through RADIUS, tell the Cisco
+ # NAS to assign it from it's own private IP pool.
+ #
+ if (!reply:Framed-IP-Address =* "") {
+ reply = {
+ Cisco-Avpair += "ip:addr-pool=privatepool"
+ }
+ }
+}