update otp_hotp() to support 6,7,8,9 digit otp's
[freeradius.git] / src / modules / rlm_linelog / rlm_linelog.c
1 /*
2  * rlm_linelog.c
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 2004  The FreeRADIUS server project
21  * Copyright 2004  Alan DeKok <aland@freeradius.org>
22  */
23
24 #include <freeradius-devel/autoconf.h>
25
26 #include <stdio.h>
27 #include <stdlib.h>
28
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32
33 #ifdef HAVE_FCNTL_H
34 #include <fcntl.h>
35 #endif
36
37 #include <freeradius-devel/radiusd.h>
38 #include <freeradius-devel/modules.h>
39 #include <freeradius-devel/conffile.h>
40
41
42 static const char rcsid[] = "$Id$";
43
44 /*
45  *      Define a structure for our module configuration.
46  *
47  *      These variables do not need to be in a structure, but it's
48  *      a lot cleaner to do so, and a pointer to the structure can
49  *      be used as the instance handle.
50  */
51 typedef struct rlm_linelog_t {
52         char            *filename;
53         char            *line;
54 } rlm_linelog_t;
55
56 /*
57  *      A mapping of configuration file names to internal variables.
58  *
59  *      Note that the string is dynamically allocated, so it MUST
60  *      be freed.  When the configuration file parse re-reads the string,
61  *      it free's the old one, and strdup's the new one, placing the pointer
62  *      to the strdup'd string into 'config.string'.  This gets around
63  *      buffer over-flows.
64  */
65 static const CONF_PARSER module_config[] = {
66         { "filename",  PW_TYPE_STRING_PTR,
67           offsetof(rlm_linelog_t,filename), NULL,  NULL},
68         { "format",  PW_TYPE_STRING_PTR,
69           offsetof(rlm_linelog_t,line), NULL,  NULL},
70         { NULL, -1, 0, NULL, NULL }             /* end the list */
71 };
72
73
74 static int linelog_detach(void *instance)
75 {
76         rlm_linelog_t *inst = instance;
77
78         if (inst->filename) free(inst->filename);
79         if (inst->line) free(inst->line);
80         
81         free(inst);
82         return 0;
83 }
84
85 /*
86  *      Instantiate the module.
87  */
88 static int linelog_instantiate(CONF_SECTION *conf, void **instance)
89 {
90         rlm_linelog_t *inst;
91
92         /*
93          *      Set up a storage area for instance data
94          */
95         inst = rad_malloc(sizeof(*inst));
96         memset(inst, 0, sizeof(*inst));
97
98         /*
99          *      If the configuration parameters can't be parsed, then
100          *      fail.
101          */
102         if (cf_section_parse(conf, inst, module_config) < 0) {
103                 linelog_detach(inst);
104                 return -1;
105         }
106
107         *instance = inst;
108
109         return 0;
110 }
111
112 static int do_linelog(void *instance, REQUEST *request)
113 {
114         int fd;
115         char *p;
116         char buffer[4096];
117         char line[1024];
118         rlm_linelog_t *inst;
119
120         inst = (rlm_linelog_t*) instance;
121
122         /*
123          *      FIXME: Check length.
124          */
125         radius_xlat(buffer, sizeof(buffer), inst->filename, request, NULL);
126
127         fd = open(buffer, O_WRONLY | O_APPEND | O_CREAT, 0600);
128         if (fd == -1) {
129                 radlog(L_ERR, "rlm_linelog: Failed to open %s: %s",
130                        buffer, strerror(errno));
131                 return RLM_MODULE_FAIL;
132         }
133
134         /*
135          *      FIXME: Check length.
136          */
137         radius_xlat(line, sizeof(line) - 1, inst->line, request, NULL);
138
139         p = strchr(line, '\n');
140         if (!p) strcat(line, "\n");
141         
142         write(fd, line, strlen(line));
143         close(fd);
144
145         return RLM_MODULE_OK;
146 }
147
148
149 /*
150  *      Externally visible module definition.
151  */
152 module_t rlm_linelog = {
153         RLM_MODULE_INIT,
154         "example",
155         RLM_TYPE_THREAD_SAFE,           /* type */
156         linelog_instantiate,            /* instantiation */
157         linelog_detach,                 /* detach */
158         {
159                 do_linelog,     /* authentication */
160                 do_linelog,     /* authorization */
161                 do_linelog,     /* preaccounting */
162                 do_linelog,     /* accounting */
163                 NULL,                   /* checksimul */
164                 do_linelog,     /* pre-proxy */
165                 do_linelog,     /* post-proxy */
166                 do_linelog      /* post-auth */
167         },
168 };