2
2
* rlm_dbm.c authorize: authorize using ndbm database
4
* Version: $Id: rlm_dbm.c,v 1.6.2.1 2003/09/12 19:18:03 phampson Exp $
4
* Version: $Id: rlm_dbm.c,v 1.9 2004/02/26 19:04:28 aland Exp $
6
6
* This program is free software; you can redistribute it and/or modify
7
7
* it under the terms of the GNU General Public License as published by
45
45
# include "sandymod.h"
48
static const char rcsid[] = "$Id: rlm_dbm.c,v 1.6.2.1 2003/09/12 19:18:03 phampson Exp $";
48
static const char rcsid[] = "$Id: rlm_dbm.c,v 1.9 2004/02/26 19:04:28 aland Exp $";
51
51
#define get_user_content dbm_fetch
75
75
static CONF_PARSER module_config[] = {
76
{ "usersfile", PW_TYPE_STRING_PTR,offsetof(struct rlm_dbm_t,userfile),
76
{ "usersfile", PW_TYPE_STRING_PTR,offsetof(struct rlm_dbm_t,userfile),
78
78
{ NULL, -1, 0, NULL, NULL }
81
81
static void sm_user_list_wipe (SM_USER_ENTRY **ue) {
83
83
SM_USER_ENTRY * pue, *nue;
85
85
if ( ! *ue ) return ;
88
88
while ( pue != NULL ) {
90
90
DEBUG2("Remove %s from user list", pue -> username);
91
91
free(pue -> username);
105
105
static int sm_user_list_add(SM_USER_ENTRY **ue, const char *un) {
108
if ( strcmp( (*ue) -> username, un) == 0 ) return 1;
108
if ( strcmp( (*ue) -> username, un) == 0 ) return 1;
109
109
ue = & ((*ue) -> next);
111
111
*ue = malloc(sizeof(SM_USER_ENTRY));
143
143
* pdb - ndbm handler
144
144
* username - user name from request
145
145
* request - pair originated from the nas
146
* mode - search mode SM_SM_ACCUM - accumulative search mode
146
* mode - search mode SM_SM_ACCUM - accumulative search mode
147
147
* out-parameters:
149
149
* parsed_users - list of parsed user names for loop removal
152
152
static int sm_parse_user(DBM *pdb, const char * username, VALUE_PAIR const* request, VALUE_PAIR **config,
153
153
VALUE_PAIR **reply, SM_USER_ENTRY **ulist)
157
157
VALUE_PAIR *vp = NULL,* tmp_config = NULL, *tmp_reply = NULL, *nu_reply = NULL;
158
158
VALUE_PAIR *join_attr;
161
int parse_state = SMP_PATTERN;
161
int parse_state = SMP_PATTERN;
162
162
int continue_search = 1;
164
164
/* check for loop */
166
166
DEBUG2("sm_parse_user.c: check for loops");
168
168
if ( (retcod = sm_user_list_add(ulist,username) ) ) {
169
169
if ( retcod < 0 ) radlog(L_ERR,"rlm_dbm: Couldn't allocate memory");
170
170
else radlog(L_ERR,"rlm_dbm: Invalid configuration: loop detected");
171
return RLM_MODULE_FAIL;
171
return RLM_MODULE_FAIL;
174
174
/* retrieve user content */
176
176
k.dptr = username;
177
177
k.dsize = strlen(username) + 1 ; /* username stored with '\0' */
179
179
d = dbm_fetch(pdb, k);
180
180
if ( d.dptr == NULL ) {
181
181
DEBUG2("rlm_dbm: User <%s> not foud in database\n",username);
182
182
return RLM_MODULE_NOTFOUND;
186
186
ch [ d.dsize - 1 ] = '\0'; /* should be closed by 0 */
188
188
DEBUG2("sm_parse_user: start parsing: user: %s", username);
190
190
/* start parse content */
191
191
while ( parse_state != SMP_ERROR && *ch && continue_search ) {
195
195
while( *ch && *ch != '\n') ch++ ;
197
197
if ( *ch == '\n' ) { *ch = 0; ch++; }
199
DEBUG2("parse buffer: <<%s>>\n",beg);
199
DEBUG2("parse buffer: <<%s>>\n",beg);
201
201
retcod = userparse(beg,&vp);
202
202
if ( retcod == T_INVALID ) librad_perror("parse error ");
204
204
switch ( retcod ) {
205
205
case T_COMMA: break; /* continue parse the current list */
206
case T_EOL: DEBUG2("rlm_dbm: recod parsed\n"); /* vp contains full pair list */
206
case T_EOL: DEBUG2("rlm_dbm: recod parsed\n"); /* vp contains full pair list */
207
207
if ( parse_state == SMP_PATTERN ) { /* pattern line found */
208
208
DEBUG2("process pattern");
209
209
/* check pattern against request */
214
214
parse_state = SMP_REPLY; /* look for reply */
217
DEBUG2("rlm_dbm: patern not matched, reply skiped");
217
DEBUG2("rlm_dbm: patern not matched, reply skiped");
219
219
while ( *ch && *ch !='\n' ) ch++;
220
220
if ( *ch == '\n' ) ch++;
223
223
/* look for join-attribute */
224
224
DEBUG2("rlm_dbm: Reply found");
226
while( (join_attr = pairfind(join_attr,SM_JOIN_ATTR) ) != NULL ) {
226
while( (join_attr = pairfind(join_attr,SM_JOIN_ATTR) ) != NULL ) {
227
227
DEBUG2("rlm_dbm: Proccess nested record: username %s",
228
228
(char *)join_attr->strvalue);
229
229
/* res = RLM_MODULE_NOTFOUND; */
230
res = sm_parse_user(pdb, (char *)join_attr->strvalue, request, &tmp_config,
230
res = sm_parse_user(pdb, (char *)join_attr->strvalue, request, &tmp_config,
231
231
&nu_reply, ulist);
232
232
DEBUG("rlm_dbm: recived: %d\n",res);
258
258
pairfree(&nu_reply); }
260
default: /* we do not wait that !!!! */
260
default: /* we do not wait that !!!! */
261
261
parse_state = SMP_ERROR;
262
262
DEBUG2("rlm_dbm: Unknown token: %d\n",retcod);
267
267
if ( parse_state == SMP_PATTERN ) {
268
pairmove(config,&tmp_config);
268
pairmove(config,&tmp_config);
269
269
pairfree(&tmp_config);
270
270
pairmove(reply,&tmp_reply);
271
271
pairfree(&tmp_reply);
283
static int sm_postprocessor(VALUE_PAIR **reply) {
283
static int sm_postprocessor(VALUE_PAIR **reply UNUSED) {
287
287
static int rlm_dbm_instantiate(CONF_SECTION *conf, void **instance) {
288
288
struct rlm_dbm_t *inst;
290
290
inst = rad_malloc(sizeof(rlm_dbm_t));
311
311
const char *name;
312
312
SM_USER_ENTRY *ulist = NULL;
315
315
struct rlm_dbm_t *inst = instance;
317
317
VALUE_PAIR **check_pairs, **reply_pairs;
319
319
request_pairs = request->packet->vps;
320
320
check_pairs = &request->config_items;
321
321
reply_pairs = &request->reply->vps;
324
324
* Grab the canonical user name.
326
326
namepair = request->username;
327
327
name = namepair ? (char *) namepair->strvalue : "NONE";
329
329
DEBUG2("rlm_dbm: try open database file: %s\n",inst -> userfile);
331
331
/* open database */
335
335
if ( found == RLM_MODULE_NOTFOUND ) {
336
336
sm_user_list_wipe(&ulist);
337
337
found = sm_parse_user(pdb, "DEFAULT", request_pairs, &check_tmp, &reply_tmp, &ulist);
341
341
found = RLM_MODULE_FAIL;
342
342
DEBUG2("rlm_dbm: Cannot open database file: %s\n",
343
343
strerror(errno));