# and actions to take.
#
# Policies are something like subroutines in a normal language, but
-# they cannot be called recursively. They MUST be defined in order.
+# they cannot be called recursively. They MUST be defined in order.
# If policy A calls policy B, then B MUST be defined before A.
#
policy {
+ #
+ # Overload the default acct_unique module, it's not smart enough
+ #
+ acct_unique {
+ #
+ # If we have a class attribute, it'll have a local value (defined by populate_class),
+ # this ensures uniqueness and suitability.
+ # We could just use the Class attribute as Acct-Unique-Session-Id, but this may cause
+ # problems with NAS that carry Class values across between multiple linked sessions.
+ # So we rehash class with Acct-Session-ID to provide a truely unique session identifier.
+ #
+ # Using a Class/Session-ID combination is more robust than using elements in the
+ # Accounting-Request, which may be subject to change, such as NAS-IP-Address
+ # or Client-IP-Address and NAS-Port-ID/NAS-Port.
+ # So should ensure that session data is not affected if NAS IP addresses change, or
+ # the client roams to a different 'port' whilst maintaining its initial authentication
+ # session (Common in a wireless environment).
+ #
+ if(Class) {
+ update request {
+ Acct-Unique-Session-Id := "%{md5:%{Class}%{Acct-Session-ID}}"
+ }
+ }
+ #
+ # Not All devices respect RFC 2865 when dealing with the class attribute,
+ # so be prepared to use the older style of hashing scheme if a class attribute is not included
+ #
+ else {
+ update request {
+ Acct-Unique-Session-Id := "%{md5:%{User-Name}%{Acct-Session-ID}%{NAS-IP-Address}%{NAS-Port-ID:}%{NAS-Port}}"
+ }
+ }
+ }
+
+ #
+ # Insert a (hopefully unique) value into class
+ #
+ insert_acct_class {
+ update reply {
+ Class = "%{md5:%t%{request:NAS-Identifier}%{NAS-Port-ID}%{NAS-Port}%{Calling-Station-ID}%{reply:User-Name}}"
+ }
+ }
+
#
# Forbid all EAP types.
#
}
#
- # If you want the server to pretend that it is dead,
- # then use the "do_not_respond" policy.
+ # If you want the server to pretend that it is dead,
+ # then use the "do_not_respond" policy.
#
do_not_respond {
update control {
}
#
- # Force some sanity on User-Name. This helps to avoid issues
+ # Filter the username
+ #
+ # Force some sanity on User-Name.This helps to avoid issues
# issues where the back-end database is "forgiving" about
# what constitutes a user name.
#
#
# Normalize the MAC Addresses in the Calling/Called-Station-Id
#
- mac-addr = ([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})
+ mac-addr-regexp = ([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})[^0-9a-f]?([0-9a-f]{2})
- # Add "rewrite.called_station_id" in the "authorize" and "preacct"
+ # Add "rewrite_called_station_id" in the "authorize" and "preacct"
# sections.
- rewrite.called_station_id {
- if((Called-Station-Id) && "%{Called-Station-Id}" =~ /^%{config:policy.mac-addr}(:(.+))?$/i) {
+ rewrite_called_station_id {
+ if(Called-Station-Id =~ /^%{config:policy.mac-addr-regexp}(:(.+))?$/i) {
update request {
Called-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
}
# SSID component?
if ("%{7}") {
update request {
- Called-Station-Id := "%{Called-Station-Id}:%{7}"
+ Called-Station-SSID := "%{7}"
}
}
updated
}
}
- # Add "rewrite.calling_station_id" in the "authorize" and "preacct"
+ # Add "rewrite_calling_station_id" in the "authorize" and "preacct"
# sections.
- rewrite.calling_station_id {
- if((Calling-Station-Id) && "%{Calling-Station-Id}" =~ /^%{config:policy.mac-addr}$/i) {
+ rewrite_calling_station_id {
+ if(Calling-Station-Id =~ /^%{config:policy.mac-addr-regexp}$/i) {
update request {
Calling-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
}