update otp_hotp() to support 6,7,8,9 digit otp's
[freeradius.git] / src / main / acct.c
1 /*
2  * acct.c       Accounting routines.
3  *
4  * Version:     $Id$
5  *
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.
10  *
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.
15  *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
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>
24  */
25
26 static const char rcsid[] = "$Id$";
27
28 #include <freeradius-devel/autoconf.h>
29 #include <freeradius-devel/radiusd.h>
30 #include <freeradius-devel/modules.h>
31
32 /*
33  *      rad_accounting: call modules.
34  *
35  *      The return value of this function isn't actually used right now, so
36  *      it's not entirely clear if it is returning the right things. --Pac.
37  */
38 int rad_accounting(REQUEST *request)
39 {
40         int result = RLM_MODULE_OK;
41
42         /*
43          *      Run the modules only once, before proxying.
44          */
45         if (!request->proxy) {
46                 VALUE_PAIR      *vp;
47                 int             acct_type = 0;
48
49                 result = module_preacct(request);
50                 switch (result) {
51                         /*
52                          *      The module has a number of OK return codes.
53                          */
54                         case RLM_MODULE_NOOP:
55                         case RLM_MODULE_OK:
56                         case RLM_MODULE_UPDATED:
57                                 break;
58                         /*
59                          *      The module handled the request, stop here.
60                          */
61                         case RLM_MODULE_HANDLED:
62                                 return result;
63                         /*
64                          *      The module failed, or said the request is
65                          *      invalid, therefore we stop here.
66                          */
67                         case RLM_MODULE_FAIL:
68                         case RLM_MODULE_INVALID:
69                         case RLM_MODULE_NOTFOUND:
70                         case RLM_MODULE_REJECT:
71                         case RLM_MODULE_USERLOCK:
72                         default:
73                                 return result;
74                 }
75
76                 /*
77                  *      Do the data storage before proxying. This is to ensure
78                  *      that we log the packet, even if the proxy never does.
79                  */
80                 vp = pairfind(request->config_items, PW_ACCT_TYPE);
81                 if (vp) {
82                         DEBUG2("  Found Acct-Type %s", vp->vp_strvalue);
83                         acct_type = vp->lvalue;
84                 }
85                 result = module_accounting(acct_type, request);
86                 switch (result) {
87                         /*
88                          *      In case the accounting module returns FAIL,
89                          *      it's still useful to send the data to the
90                          *      proxy.
91                          */
92                         case RLM_MODULE_FAIL:
93                         case RLM_MODULE_NOOP:
94                         case RLM_MODULE_OK:
95                         case RLM_MODULE_UPDATED:
96                                 break;
97                         /*
98                          *      The module handled the request, don't reply.
99                          */
100                         case RLM_MODULE_HANDLED:
101                                 return result;
102                         /*
103                          *      Neither proxy, nor reply to invalid requests.
104                          */
105                         case RLM_MODULE_INVALID:
106                         case RLM_MODULE_NOTFOUND:
107                         case RLM_MODULE_REJECT:
108                         case RLM_MODULE_USERLOCK:
109                         default:
110                                 return result;
111                 }
112
113                 /*
114                  *      Maybe one of the preacct modules has decided
115                  *      that a proxy should be used.
116                  */
117                 if ((vp = pairfind(request->config_items, PW_PROXY_TO_REALM))) {
118                         REALM *realm;
119
120                         /*
121                          *      Check whether Proxy-To-Realm is
122                          *      a LOCAL realm.
123                          */
124                         realm = realm_find(vp->vp_strvalue, TRUE);
125                         if (realm != NULL &&
126                             realm->acct_ipaddr.af == AF_INET &&
127                             realm->acct_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_NONE)) {
128                                 DEBUG("rad_accounting: Cancelling proxy to realm %s, as it is a LOCAL realm.", realm->realm);
129                                 pairdelete(&request->config_items, PW_PROXY_TO_REALM);
130                         } else {
131                                 /*
132                                  *      Don't reply to the NAS now because
133                                  *      we have to send the proxied packet
134                                  *      before that.
135                                  */
136                                 return result;
137                         }
138                 }
139         }
140
141         /*
142          *      We get here IF we're not proxying, OR if we've
143          *      received the accounting reply from the end server,
144          *      THEN we can reply to the NAS.
145          *      If the accounting module returns NOOP, the data
146          *      storage did not succeed, so radiusd should not send
147          *      Accounting-Response.
148          */
149         switch (result) {
150                 /*
151                  *      Send back an ACK to the NAS.
152                  */
153                 case RLM_MODULE_OK:
154                 case RLM_MODULE_UPDATED:
155                         request->reply->code = PW_ACCOUNTING_RESPONSE;
156                         break;
157                 /*
158                  *      The module handled the request, don't reply.
159                  */
160                 case RLM_MODULE_HANDLED:
161                         break;
162                 /*
163                  *      Failed to log or to proxy the accounting data,
164                  *      therefore don't reply to the NAS.
165                  */
166                 case RLM_MODULE_FAIL:
167                 case RLM_MODULE_INVALID:
168                 case RLM_MODULE_NOOP:
169                 case RLM_MODULE_NOTFOUND:
170                 case RLM_MODULE_REJECT:
171                 case RLM_MODULE_USERLOCK:
172                 default:
173                         break;
174         }
175         return result;
176 }