18dc683b6337be6adef6e30e0e7a13308165aa01
[freeradius.git] / raddb / policy.conf
1 # -*- text -*-
2 ##
3 ## policy.conf  -- FreeRADIUS server configuration file.
4 ##
5 ##      http://www.freeradius.org/
6 ##      $Id$
7 ##
8
9 #
10 #  Policies are virtual modules, similar to those defined in the
11 #  "instantate" section of radiusd.conf.
12 #
13 #  Defining a policy here means that it can be referenced in multiple
14 #  places as a *name*, rather than as a series of conditions to match,
15 #  and actions to take.
16 #
17 #  Policies are something like subroutines in a normal language, but
18 #  they cannot be called recursively. They MUST be defined in order.
19 #  If policy A calls policy B, then B MUST be defined before A.
20 #
21 policy {
22         #
23         #       Overload the default acct_unique module, it's not smart enough
24         #
25         acct_unique {
26                 #
27                 #  If we have a class attribute, it'll have a local value (defined by populate_class),
28                 #  this ensures uniqueness and suitability.
29                 #  We could just use the Class attribute as Acct-Unique-Session-Id, but this may cause
30                 #  problems with NAS that carry Class values across between multiple linked sessions.
31                 #  So we rehash class with Acct-Session-ID to provide a truely unique session identifier.
32                 #
33                 #  Using a Class/Session-ID combination is more robust than using elements in the
34                 #  Accounting-Request, which may be subject to change, such as NAS-IP-Address
35                 #  or Client-IP-Address and NAS-Port-ID/NAS-Port.
36                 #  So should ensure that session data is not affected if NAS IP addresses change, or
37                 #  the client roams to a different 'port' whilst maintaining its initial authentication
38                 #  session (Common in a wireless environment).
39                 #        
40                 if(Class) {
41                         update request {
42                                 Acct-Unique-Session-Id := "%{md5:%{Class}%{Acct-Session-ID}}"
43                         }
44                 }        
45                 #
46                 #  Not All devices respect RFC 2865 when dealing with the class attribute,
47                 #  so be prepared to use the older style of hashing scheme if a class attribute is not included 
48                 #
49                 else {
50                         update request {
51                                 Acct-Unique-Session-Id := "%{md5:%{User-Name}%{Acct-Session-ID}%{NAS-IP-Address}%{NAS-Port-ID:}%{NAS-Port}}" 
52                          }       
53                 }        
54         }        
55
56         #
57         #       Insert a (hopefully unique) value into class
58         #
59         insert_acct_class {
60                 update reply { 
61                         Class = "%{md5:%t%{request:NAS-Identifier}%{NAS-Port-ID}%{NAS-Port}%{Calling-Station-ID}%{reply:User-Name}}"
62                 }
63         }
64
65         #
66         #       Forbid all EAP types.
67         #
68         forbid_eap {
69                 if (EAP-Message) {
70                         reject
71                 }
72         }
73
74         #
75         #       Forbid all non-EAP types outside of an EAP tunnel.
76         #
77         permit_only_eap {
78                 if (!EAP-Message) {
79                         #  We MAY be inside of a TTLS tunnel.
80                         #  PEAP and EAP-FAST require EAP inside of
81                         #  the tunnel, so this check is OK.
82                         #  If so, then there MUST be an outer EAP message.
83                         if (!"%{outer.request:EAP-Message}") {
84                                 reject
85                         }
86                 }
87         }
88
89         #
90         #       Forbid all attempts to login via realms.
91         #
92         deny_realms {
93                 if (User-Name =~ /@|\\/) {
94                         reject
95                 }
96         }
97
98         #
99         #  If you want the server to pretend that it is dead,
100         #  then use the "do_not_respond" policy.
101         #
102         do_not_respond {
103                 update control {
104                         Response-Packet-Type := Do-Not-Respond
105                 }
106
107                 handled
108         }
109
110         #
111         #       Filter the username
112         #
113         #  Force some sanity on User-Name.This helps to avoid issues
114         #  issues where the back-end database is "forgiving" about
115         #  what constitutes a user name.
116         #
117         filter_username {
118                 # spaces at the start: reject
119                 if (User-Name =~ /^ /) {
120                         reject
121                 }
122
123                 # spaces at the end: reject
124                 if (User-Name =~ / $$/) {
125                         reject
126                 }
127
128                 # Mixed case: reject
129                 if (User-Name != "%{tolower:%{User-Name}}") {
130                         reject
131                 }
132         }
133
134
135         #       
136         #  The following policies are for the Chargeable-User-Identity
137         #  (CUI) configuration.
138         #
139
140         #
141         #  The client indicates it can do CUI by sending a CUI attribute        
142         #  containing one zero byte
143         #
144         cui_authorize {
145                 update request {
146                         Chargeable-User-Identity:='\\000'
147                 }
148         }
149
150         #
151         #  Add a CUI attribute based on the User-Name, and a secret key
152         #  known only to this server.
153         #
154         cui_postauth {
155                 if (FreeRadius-Proxied-To == 127.0.0.1) {
156                         if (outer.request:Chargeable-User-Identity) {
157                                 update outer.reply {
158                                         Chargeable-User-Identity:="%{md5:%{config:cui_hash_key}%{User-Name}}"
159                                 }
160                         }
161                 }
162                 else {
163                         if (Chargeable-User-Identity) {
164                                 update reply {
165                                         Chargeable-User-Identity="%{md5:%{config:cui_hash_key}%{User-Name}}"
166                                 }
167                         }
168                 }
169         }
170
171         #
172         #  If there is a CUI attribute in the reply, add it to the DB.
173         #
174         cui_updatedb {
175                 if (reply:Chargeable-User-Identity) {
176                         cui
177                 }
178         }
179
180         #
181         #  If we had stored a CUI for the User, add it to the request.
182         #
183         cui_accounting {
184                 #
185                 #  If the CUI isn't in the packet, see if we can find it
186                 #  in the DB.
187                 #
188                 if (!Chargeable-User-Identity) {
189                         update control {
190                                 Chargable-User-Identity := "%{cui: SELECT cui FROM cui WHERE clientipaddress = '%{Client-IP-Address}' AND callingstationid = '%{Calling-Station-Id}' AND username = '%{User-Name}'}"
191                         }
192                 }
193
194                 #
195                 #  If it exists now, then write out when we last saw
196                 #  this CUI.
197                 #
198                 if (Chargeable-User-Identity && (Chargeable-User-Identity != "")) {
199                         cui
200                 }
201         }
202
203         #
204         #  Normalize the MAC Addresses in the Calling/Called-Station-Id
205         #
206         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})
207
208         #  Add "rewrite_called_station_id" in the "authorize" and "preacct"
209         #  sections.
210         rewrite_called_station_id {
211                 if(Called-Station-Id =~ /^%{config:policy.mac-addr-regexp}(:(.+))?$/i) {
212                         update request {
213                                 Called-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
214                         }
215
216                         # SSID component?
217                         if ("%{7}") {
218                                 update request {
219                                         Called-Station-SSID := "%{7}"
220                                 }
221                         }
222                         updated
223                 }
224                 else {
225                         noop
226                 }
227         }
228
229         #  Add "rewrite_calling_station_id" in the "authorize" and "preacct"
230         #  sections.
231         rewrite_calling_station_id {
232                 if(Calling-Station-Id =~ /^%{config:policy.mac-addr-regexp}$/i) {
233                         update request {
234                                 Calling-Station-Id := "%{tolower:%{1}-%{2}-%{3}-%{4}-%{5}-%{6}}"
235                         }
236                         updated
237                 }
238                 else {
239                         noop
240                 }
241         }
242 }