import from branch_1_1:
[freeradius.git] / src / modules / rlm_acctlog / rlm_acctlog.c
1 /*
2  *       rlm_acctlog.c
3  *
4  *   This program is free software; you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation; either version 2 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *   GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program; if not, write to the Free Software
16  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  *
18  *   Copyright 2006 Suntel Communications - www.suntel.com.tr
19  *   Copyright 2006 The FreeRADIUS server project
20  *
21  *   Tuyan Ozipek
22  *   Peter Nixon
23  */
24
25 #include <freeradius-devel/ident.h>
26 RCSID("$Id$")
27
28 #include <freeradius-devel/radiusd.h>
29 #include <freeradius-devel/modules.h>
30
31 typedef struct rlm_acctlog_t {
32     char        *acctstart;
33     char        *acctstop;
34         char            *acctupdate;
35     char        *accton;
36         char            *acctoff;
37
38 } rlm_acctlog_t;
39
40 static const CONF_PARSER module_config[] = {
41     { "acctlog_update",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, acctupdate), NULL,  ""},
42     { "acctlog_start",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, acctstart), NULL,  ""},
43     { "acctlog_stop",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, acctstop), NULL,  ""},
44     { "acctlog_on",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, accton), NULL,  ""},
45     { "acctlog_off",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, acctoff), NULL,  ""},
46     { NULL, -1, 0, NULL, NULL }     /* end the list */
47 };
48
49
50 static int acctlog_detach(void *instance)
51 {
52     rlm_acctlog_t *inst = instance;
53
54
55     free(inst);
56     return 0;
57 }
58
59 static int acctlog_instantiate(CONF_SECTION *conf, void **instance)
60 {
61         rlm_acctlog_t *inst;
62
63     inst = rad_malloc(sizeof(*inst));
64     memset(inst, 0, sizeof(*inst));
65
66         if (cf_section_parse(conf, inst, module_config) < 0) {
67                 acctlog_detach(inst);
68                 return -1;
69         }
70
71         *instance = inst;
72
73     return 0;
74
75 }
76
77 static int do_acctlog_acct(void *instance, REQUEST *request)
78 {
79         rlm_acctlog_t *inst;
80         VALUE_PAIR *pair;
81
82         char    logstr[MAX_STRING_LEN];
83         int     acctstatustype = 0;
84
85
86         inst = (rlm_acctlog_t*) instance;
87
88     if ((pair = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) != NULL) {
89         acctstatustype = pair->vp_integer;
90     } else {
91         radius_xlat(logstr, sizeof(logstr), "packet has no accounting status type. [user '%{User-Name}', nas '%{NAS-IP-Address}']", request, NULL);
92         radlog(L_ERR, "rlm_acctlog (%s)", logstr);
93         return RLM_MODULE_INVALID;
94     }
95
96         switch (acctstatustype) {
97                 case PW_STATUS_START:
98                         radius_xlat(logstr, sizeof(logstr), inst->acctstart, request, NULL);
99                 break;
100                 case PW_STATUS_STOP:
101                         radius_xlat(logstr, sizeof(logstr), inst->acctstop, request, NULL);
102                 break;
103                 case PW_STATUS_ALIVE:
104                         radius_xlat(logstr, sizeof(logstr), inst->acctupdate, request, NULL);
105                 break;
106                 case PW_STATUS_ACCOUNTING_ON:
107                         radius_xlat(logstr, sizeof(logstr), inst->accton, request, NULL);
108                 break;
109                 case PW_STATUS_ACCOUNTING_OFF:
110                         radius_xlat(logstr, sizeof(logstr), inst->acctoff, request, NULL);
111                 break;
112
113         }
114
115         if (strlen(logstr))
116                 radlog(L_ACCT,"%s", logstr);
117
118         return RLM_MODULE_OK;
119 }
120
121 /*
122  *  Externally visible module definition.
123  */
124 module_t rlm_acctlog = {
125     RLM_MODULE_INIT,
126     "acctlog",
127     RLM_TYPE_THREAD_SAFE,       /* type */
128     acctlog_instantiate,        /* instantiation */
129     acctlog_detach,         /* detach */
130     {
131         NULL, /* authentication */
132         NULL, /* authorization */
133         NULL, /* preaccounting */
134         do_acctlog_acct, /* accounting */
135         NULL,       /* checksimul */
136         NULL,     /* pre-proxy */
137         NULL, /* post-proxy */
138         NULL  /* post-auth */
139     },
140 };
141