include <string.h> if necessary, too
[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/autoconf.h>
29
30 #include <stdio.h>
31 #include <stdlib.h>
32
33 #include <freeradius-devel/radiusd.h>
34 #include <freeradius-devel/modules.h>
35 #include <freeradius-devel/conffile.h>
36
37 typedef struct rlm_acctlog_t {
38     char        *acctstart;
39     char        *acctstop;
40         char            *acctupdate;
41     char        *accton;
42         char            *acctoff;
43
44 } rlm_acctlog_t;
45
46 static const CONF_PARSER module_config[] = {
47     { "acctlog_update",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, acctupdate), NULL,  ""},
48     { "acctlog_start",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, acctstart), NULL,  ""},
49     { "acctlog_stop",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, acctstop), NULL,  ""},
50     { "acctlog_on",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, accton), NULL,  ""},
51     { "acctlog_off",  PW_TYPE_STRING_PTR, offsetof(rlm_acctlog_t, acctoff), NULL,  ""},
52     { NULL, -1, 0, NULL, NULL }     /* end the list */
53 };
54
55
56 static int acctlog_detach(void *instance)
57 {   
58     rlm_acctlog_t *inst = instance;
59         
60         
61     free(inst);
62     return 0;
63 }
64
65 static int acctlog_instantiate(CONF_SECTION *conf, void **instance)
66 {
67         rlm_acctlog_t *inst;
68
69     inst = rad_malloc(sizeof(*inst));
70     memset(inst, 0, sizeof(*inst));
71
72         if (cf_section_parse(conf, inst, module_config) < 0) {
73                 acctlog_detach(inst);
74                 return -1;
75         }
76
77         *instance = inst;
78
79     return 0;
80
81 }
82
83 static int do_acctlog_acct(void *instance, REQUEST *request)
84 {
85         rlm_acctlog_t *inst;
86         VALUE_PAIR *pair;
87
88         char    logstr[MAX_STRING_LEN];
89         int     acctstatustype = 0;
90
91
92         inst = (rlm_acctlog_t*) instance;
93
94     if ((pair = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) != NULL) {
95         acctstatustype = pair->lvalue;
96     } else {
97         radius_xlat(logstr, sizeof(logstr), "packet has no accounting status type. [user '%{User-Name}', nas '%{NAS-IP-Address}']", request, NULL);
98         radlog(L_ERR, "rlm_acctlog (%s)", logstr);
99         return RLM_MODULE_INVALID;
100     }
101
102         switch (acctstatustype) {
103                 case PW_STATUS_START:
104                         radius_xlat(logstr, sizeof(logstr), inst->acctstart, request, NULL);
105                 break;
106                 case PW_STATUS_STOP:
107                         radius_xlat(logstr, sizeof(logstr), inst->acctstop, request, NULL);
108                 break;
109                 case PW_STATUS_ALIVE:
110                         radius_xlat(logstr, sizeof(logstr), inst->acctupdate, request, NULL);
111                 break;
112                 case PW_STATUS_ACCOUNTING_ON:
113                         radius_xlat(logstr, sizeof(logstr), inst->accton, request, NULL);
114                 break;
115                 case PW_STATUS_ACCOUNTING_OFF:
116                         radius_xlat(logstr, sizeof(logstr), inst->acctoff, request, NULL);
117                 break;
118                 
119         }
120
121         if (strlen(logstr))
122                 radlog(L_ACCT,"%s", logstr);
123
124         return RLM_MODULE_OK;
125 }
126
127 /*
128  *  Externally visible module definition.
129  */
130 module_t rlm_acctlog = {
131     RLM_MODULE_INIT,
132     "acctlog",
133     RLM_TYPE_THREAD_SAFE,       /* type */
134     acctlog_instantiate,        /* instantiation */
135     acctlog_detach,         /* detach */
136     {
137         NULL, /* authentication */
138         NULL, /* authorization */
139         NULL, /* preaccounting */
140         do_acctlog_acct, /* accounting */
141         NULL,       /* checksimul */
142         NULL,     /* pre-proxy */
143         NULL, /* post-proxy */
144         NULL  /* post-auth */
145     },
146 };
147