Massively cleaned up #include's, so they're in a consistent
[freeradius.git] / src / main / acct.c
index 812e150..367f118 100644 (file)
  * acct.c      Accounting routines.
  *
  * Version:    $Id$
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
+ * Copyright 2000  Alan DeKok <aland@ox.org>
+ * Copyright 2000  Alan Curry <pacman@world.std.com>
  */
 
-static const char rcsid[] = "$Id$";
-
-#include       "autoconf.h"
-
-#include       <stdlib.h>
-#include       <string.h>
-
-#include       "radiusd.h"
-#include       "modules.h"
+#include <freeradius-devel/ident.h>
+RCSID("$Id$")
 
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/modules.h>
 
 /*
  *     rad_accounting: call modules.
+ *
+ *     The return value of this function isn't actually used right now, so
+ *     it's not entirely clear if it is returning the right things. --Pac.
  */
 int rad_accounting(REQUEST *request)
 {
-       int             reply;
+       int result = RLM_MODULE_OK;
 
        /*
-        *      FIXME: Prefix= and Suffix= support needs to be added!
-        *
-        *      We need to get the Prefix= and Suffix= things from
-        *      the users file to apply.
-        *      In 1.5.4.3, we used presuf_setup() but that is
-        *      not possible anymore. Perhaps we need an extra
-        *      module entry point for this ?
+        *      Run the modules only once, before proxying.
         */
-       /* Like preacct? */
-
-       if(!request->proxy) { /* Only need to do this once, before proxying */
-         reply = module_preacct(request);
-         if (reply != RLM_MODULE_OK)
-                 return RLM_MODULE_FAIL;
+       if (!request->proxy) {
+               VALUE_PAIR      *vp;
+               int             acct_type = 0;
 
-         /* Maybe one of the preacct modules has decided that a proxy should
-          * be used. If so, get out of here and send the packet. */
-         if(pairfind(request->config_items, PW_PROXY_TO_REALM))
-                 return 0;
-       }
+               result = module_preacct(request);
+               switch (result) {
+                       /*
+                        *      The module has a number of OK return codes.
+                        */
+                       case RLM_MODULE_NOOP:
+                       case RLM_MODULE_OK:
+                       case RLM_MODULE_UPDATED:
+                               break;
+                       /*
+                        *      The module handled the request, stop here.
+                        */
+                       case RLM_MODULE_HANDLED:
+                               return result;
+                       /*
+                        *      The module failed, or said the request is
+                        *      invalid, therefore we stop here.
+                        */
+                       case RLM_MODULE_FAIL:
+                       case RLM_MODULE_INVALID:
+                       case RLM_MODULE_NOTFOUND:
+                       case RLM_MODULE_REJECT:
+                       case RLM_MODULE_USERLOCK:
+                       default:
+                               return result;
+               }
 
-       reply = RLM_MODULE_OK;
-       if (!request->proxy) {
                /*
-                *      Keep the radutmp file in sync.
+                *      Do the data storage before proxying. This is to ensure
+                *      that we log the packet, even if the proxy never does.
                 */
-               radutmp_add(request);
+               vp = pairfind(request->config_items, PW_ACCT_TYPE);
+               if (vp) {
+                       DEBUG2("  Found Acct-Type %s", vp->vp_strvalue);
+                       acct_type = vp->lvalue;
+               }
+               result = module_accounting(acct_type, request);
+               switch (result) {
+                       /*
+                        *      In case the accounting module returns FAIL,
+                        *      it's still useful to send the data to the
+                        *      proxy.
+                        */
+                       case RLM_MODULE_FAIL:
+                       case RLM_MODULE_NOOP:
+                       case RLM_MODULE_OK:
+                       case RLM_MODULE_UPDATED:
+                               break;
+                       /*
+                        *      The module handled the request, don't reply.
+                        */
+                       case RLM_MODULE_HANDLED:
+                               return result;
+                       /*
+                        *      Neither proxy, nor reply to invalid requests.
+                        */
+                       case RLM_MODULE_INVALID:
+                       case RLM_MODULE_NOTFOUND:
+                       case RLM_MODULE_REJECT:
+                       case RLM_MODULE_USERLOCK:
+                       default:
+                               return result;
+               }
 
                /*
-                *      Do accounting and if OK, reply.
+                *      Maybe one of the preacct modules has decided
+                *      that a proxy should be used.
                 */
-               reply = module_accounting(request);
+               if ((vp = pairfind(request->config_items, PW_PROXY_TO_REALM))) {
+                       REALM *realm;
+
+                       /*
+                        *      Check whether Proxy-To-Realm is
+                        *      a LOCAL realm.
+                        */
+                       realm = realm_find(vp->vp_strvalue);
+                       if (realm && !realm->acct_pool) {
+                               DEBUG("rad_accounting: Cancelling proxy to realm %s, as it is a LOCAL realm.", realm->name);
+                               pairdelete(&request->config_items, PW_PROXY_TO_REALM);
+                       } else {
+                               /*
+                                *      Don't reply to the NAS now because
+                                *      we have to send the proxied packet
+                                *      before that.
+                                */
+                               return result;
+                       }
+               }
        }
-       if (reply == RLM_MODULE_OK) {
+
+       /*
+        *      We get here IF we're not proxying, OR if we've
+        *      received the accounting reply from the end server,
+        *      THEN we can reply to the NAS.
+        *      If the accounting module returns NOOP, the data
+        *      storage did not succeed, so radiusd should not send
+        *      Accounting-Response.
+        */
+       switch (result) {
                /*
-                *      Now send back an ACK to the NAS.
+                *      Send back an ACK to the NAS.
                 */
-               request->reply->code = PW_ACCOUNTING_RESPONSE;
-               reply = RLM_MODULE_OK;
+               case RLM_MODULE_OK:
+               case RLM_MODULE_UPDATED:
+                       request->reply->code = PW_ACCOUNTING_RESPONSE;
+                       break;
+               /*
+                *      The module handled the request, don't reply.
+                */
+               case RLM_MODULE_HANDLED:
+                       break;
+               /*
+                *      Failed to log or to proxy the accounting data,
+                *      therefore don't reply to the NAS.
+                */
+               case RLM_MODULE_FAIL:
+               case RLM_MODULE_INVALID:
+               case RLM_MODULE_NOOP:
+               case RLM_MODULE_NOTFOUND:
+               case RLM_MODULE_REJECT:
+               case RLM_MODULE_USERLOCK:
+               default:
+                       break;
        }
-
-       return reply;
+       return result;
 }
-