2 * acct.c Accounting routines.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Copyright 2000 The FreeRADIUS server project
21 * Copyright 2000 Miquel van Smoorenburg <miquels@cistron.nl>
22 * Copyright 2000 Alan DeKok <aland@ox.org>
23 * Copyright 2000 Alan Curry <pacman@world.std.com>
26 static const char rcsid[] = "$Id$";
36 * rad_accounting: call modules.
38 * The return value of this function isn't actually used right now, so
39 * it's not entirely clear if it is returning the right things. --Pac.
41 int rad_accounting(REQUEST *request)
43 int result = RLM_MODULE_OK;
46 * Run the modules only once, before proxying.
48 if (!request->proxy) {
55 result = module_preacct(request);
58 * The module has a number of OK return codes.
62 case RLM_MODULE_UPDATED:
65 * The module handled the request, stop here.
67 case RLM_MODULE_HANDLED:
70 * The module failed, or said the request is
71 * invalid, therefore we stop here.
74 case RLM_MODULE_INVALID:
75 case RLM_MODULE_NOTFOUND:
76 case RLM_MODULE_REJECT:
77 case RLM_MODULE_USERLOCK:
83 * Do the data storage before proxying. This is to ensure
84 * that we log the packet, even if the proxy never does.
86 vp = pairfind(request->config_items, PW_ACCT_TYPE);
88 DEBUG2(" Found Acct-Type %s", vp->strvalue);
89 acct_type = vp->lvalue;
91 result = module_accounting(acct_type, request);
94 * In case the accounting module returns FAIL,
95 * it's still useful to send the data to the
101 case RLM_MODULE_UPDATED:
104 * The module handled the request, don't reply.
106 case RLM_MODULE_HANDLED:
109 * Neither proxy, nor reply to invalid requests.
111 case RLM_MODULE_INVALID:
112 case RLM_MODULE_NOTFOUND:
113 case RLM_MODULE_REJECT:
114 case RLM_MODULE_USERLOCK:
120 * See if we need to execute a program.
121 * FIXME: somehow cache this info, and only execute the
122 * program when we receive an Accounting-START packet.
123 * Only at that time we know dynamic IP etc.
127 if ((vp = pairfind(request->reply->vps, PW_EXEC_PROGRAM)) != NULL) {
129 exec_program = strdup((char *)vp->strvalue);
130 pairdelete(&request->reply->vps, PW_EXEC_PROGRAM);
133 if ((vp = pairfind(request->reply->vps, PW_EXEC_PROGRAM_WAIT)) != NULL) {
136 exec_program = strdup((char *)vp->strvalue);
137 pairdelete(&request->reply->vps, PW_EXEC_PROGRAM_WAIT);
141 * If we want to exec a program, but wait for it,
142 * do it first before sending the reply, or
143 * proxying the packet.
145 * If we're NOT waiting, then also do this now, but
146 * don't check the return code.
150 * Wait for the answer.
151 * Don't look for a user message.
152 * Do look for returned VP's.
154 rcode = radius_exec_program(exec_program, request,
156 request->packet->vps, &vp);
160 * Always add the value-pairs to the reply.
162 * If we're not waiting, then the pairs
163 * will be empty, so this won't matter.
165 pairmove(&request->reply->vps, &vp);
176 * Maybe one of the preacct modules has decided
177 * that a proxy should be used.
179 if ((vp = pairfind(request->config_items, PW_PROXY_TO_REALM))) {
183 * Check whether Proxy-To-Realm is
186 realm = realm_find(vp->strvalue, TRUE);
188 realm->acct_ipaddr == htonl(INADDR_NONE)) {
189 DEBUG("rad_accounting: Cancelling proxy to realm %s, as it is a LOCAL realm.", realm->realm);
190 pairdelete(&request->config_items, PW_PROXY_TO_REALM);
193 * Don't reply to the NAS now because
194 * we have to send the proxied packet
203 * We get here IF we're not proxying, OR if we've
204 * received the accounting reply from the end server,
205 * THEN we can reply to the NAS.
206 * If the accounting module returns NOOP, the data
207 * storage did not succeed, so radiusd should not send
208 * Accounting-Response.
212 * Send back an ACK to the NAS.
215 case RLM_MODULE_UPDATED:
216 request->reply->code = PW_ACCOUNTING_RESPONSE;
219 * The module handled the request, don't reply.
221 case RLM_MODULE_HANDLED:
224 * Failed to log or to proxy the accounting data,
225 * therefore don't reply to the NAS.
227 case RLM_MODULE_FAIL:
228 case RLM_MODULE_INVALID:
229 case RLM_MODULE_NOOP:
230 case RLM_MODULE_NOTFOUND:
231 case RLM_MODULE_REJECT:
232 case RLM_MODULE_USERLOCK: