All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
acct.c
Go to the documentation of this file.
1 /*
2  * acct.c Accounting routines.
3  *
4  * Version: $Id: 295bc8e61da49837d8c58ec57d136ca5ee89fc95 $
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,2006 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 RCSID("$Id: 295bc8e61da49837d8c58ec57d136ca5ee89fc95 $")
27 
28 #include <freeradius-devel/radiusd.h>
29 #include <freeradius-devel/modules.h>
30 
31 #ifdef WITH_ACCOUNTING
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 #ifdef WITH_PROXY
44 #define WAS_PROXIED (request->proxy)
45 #else
46 #define WAS_PROXIED (0)
47 #endif
48 
49  /*
50  * Run the modules only once, before proxying.
51  */
52  if (!WAS_PROXIED) {
53  VALUE_PAIR *vp;
54  int acct_type = 0;
55 
56  result = module_preacct(request);
57  switch (result) {
58  /*
59  * The module has a number of OK return codes.
60  */
61  case RLM_MODULE_NOOP:
62  case RLM_MODULE_OK:
63  case RLM_MODULE_UPDATED:
64  break;
65  /*
66  * The module handled the request, stop here.
67  */
68  case RLM_MODULE_HANDLED:
69  return result;
70  /*
71  * The module failed, or said the request is
72  * invalid, therefore we stop here.
73  */
74  case RLM_MODULE_FAIL:
75  case RLM_MODULE_INVALID:
77  case RLM_MODULE_REJECT:
79  default:
80  return result;
81  }
82 
83  /*
84  * Do the data storage before proxying. This is to ensure
85  * that we log the packet, even if the proxy never does.
86  */
87  vp = fr_pair_find_by_num(request->config, 0, PW_ACCT_TYPE, TAG_ANY);
88  if (vp) {
89  acct_type = vp->vp_integer;
90  DEBUG2(" Found Acct-Type %s",
91  fr_dict_enum_name_by_da(NULL, vp->da, acct_type));
92  }
93  result = process_accounting(acct_type, request);
94  switch (result) {
95  /*
96  * In case the accounting module returns FAIL,
97  * it's still useful to send the data to the
98  * proxy.
99  */
100  case RLM_MODULE_FAIL:
101  case RLM_MODULE_NOOP:
102  case RLM_MODULE_OK:
103  case RLM_MODULE_UPDATED:
104  break;
105  /*
106  * The module handled the request, don't reply.
107  */
108  case RLM_MODULE_HANDLED:
109  return result;
110  /*
111  * Neither proxy, nor reply to invalid requests.
112  */
113  case RLM_MODULE_INVALID:
114  case RLM_MODULE_NOTFOUND:
115  case RLM_MODULE_REJECT:
116  case RLM_MODULE_USERLOCK:
117  default:
118  return result;
119  }
120 
121  /*
122  * Maybe one of the preacct modules has decided
123  * that a proxy should be used.
124  */
125  if ((vp = fr_pair_find_by_num(request->config, 0, PW_PROXY_TO_REALM, TAG_ANY))) {
126  REALM *realm;
127 
128  /*
129  * Check whether Proxy-To-Realm is
130  * a LOCAL realm.
131  */
132  realm = realm_find2(vp->vp_strvalue);
133  if (realm && !realm->acct_pool) {
134  DEBUG("rad_accounting: Cancelling proxy to realm %s, as it is a LOCAL realm.", realm->name);
135  fr_pair_delete_by_num(&request->config, 0, PW_PROXY_TO_REALM, TAG_ANY);
136  } else {
137  /*
138  * Don't reply to the NAS now because
139  * we have to send the proxied packet
140  * before that.
141  */
142  return result;
143  }
144  }
145  }
146 
147 #ifdef WITH_PROXY
148  /*
149  * We didn't see a reply to the proxied request. Fail.
150  */
151  if (request->proxy && !request->proxy_reply) return RLM_MODULE_FAIL;
152 #endif
153 
154  /*
155  * We get here IF we're not proxying, OR if we've
156  * received the accounting reply from the end server,
157  * THEN we can reply to the NAS.
158  * If the accounting module returns NOOP, the data
159  * storage did not succeed, so radiusd should not send
160  * Accounting-Response.
161  */
162  switch (result) {
163  /*
164  * Send back an ACK to the NAS.
165  */
166  case RLM_MODULE_OK:
167  case RLM_MODULE_UPDATED:
169  break;
170 
171  /*
172  * Failed to log or to proxy the accounting data,
173  * therefore don't reply to the NAS.
174  */
175  case RLM_MODULE_FAIL:
176  case RLM_MODULE_INVALID:
177  case RLM_MODULE_NOOP:
178  case RLM_MODULE_NOTFOUND:
179  case RLM_MODULE_REJECT:
180  case RLM_MODULE_USERLOCK:
181  default:
182  break;
183  }
184  return result;
185 }
186 #endif
REALM * realm_find2(char const *name)
Definition: realms.c:2201
VALUE_PAIR * config
VALUE_PAIR (s) used to set per request parameters for modules and the server core at runtime...
Definition: radiusd.h:227
RADIUS_PACKET * proxy_reply
Incoming response from proxy server.
Definition: radiusd.h:238
The module is OK, continue.
Definition: radiusd.h:91
Definition: realms.h:178
char const * fr_dict_enum_name_by_da(fr_dict_t *dict, fr_dict_attr_t const *da, int value)
Lookup the name of an enum value in a fr_dict_attr_t.
Definition: dict.c:3688
The module considers the request invalid.
Definition: radiusd.h:93
RFC2866 - Accounting-Response.
Definition: radius.h:96
RADIUS_PACKET * proxy
Outgoing request to proxy server.
Definition: radiusd.h:237
Reject the request (user is locked out).
Definition: radiusd.h:94
#define WAS_PROXIED
#define DEBUG(fmt,...)
Definition: log.h:175
#define DEBUG2(fmt,...)
Definition: log.h:176
Immediately reject the request.
Definition: radiusd.h:89
unsigned int code
Packet code (type).
Definition: libradius.h:155
rlm_rcode_t process_accounting(int type, REQUEST *request)
Definition: modules.c:2123
Stores an attribute, a value and various bits of other data.
Definition: pair.h:112
RADIUS_PACKET * reply
Outgoing response.
Definition: radiusd.h:225
void fr_pair_delete_by_num(VALUE_PAIR **head, unsigned int vendor, unsigned int attr, int8_t tag)
Delete matching pairs.
Definition: pair.c:797
rlm_rcode_t module_preacct(REQUEST *request)
Definition: modules.c:2115
Module succeeded without doing anything.
Definition: radiusd.h:96
int rad_accounting(REQUEST *request)
Definition: acct.c:38
Module failed, don't reply.
Definition: radiusd.h:90
#define TAG_ANY
Definition: pair.h:191
char const * name
Definition: realms.h:179
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
Definition: pair.c:639
fr_dict_attr_t const * da
Dictionary attribute defines the attribute.
Definition: pair.h:113
home_pool_t * acct_pool
Definition: realms.h:184
User not found.
Definition: radiusd.h:95
#define RCSID(id)
Definition: build.h:135
OK (pairs modified).
Definition: radiusd.h:97
The module handled the request, so stop.
Definition: radiusd.h:92