#
-# Sample of a policy language.
-# There's no documentation other than this file.
-# The syntax is odd, but it works.
-# It's not intended for production use.
-# Use it if you want obscure error messages and possibly server crashes.
+# 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$
#
#
#debug print_tokens # as we're parsing this file
debug print_policy # once the file has been parsed
-debug evaluate # print limited information during evaluation
+
+# 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.
#
policy authorize {
if (CHAP-Password) {
- if (!(CHAP-Challenge)) {
+ if (!CHAP-Challenge) {
print "Adding CHAP-Challenge = %{request:Packet-Authentication-Vector}\n"
#
#
# 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"
+ }
+ }
+}