1 |
/* This file is part of GNU RADIUS. |
/* This file is part of GNU Radius. |
2 |
Copyright (C) 2002, Free Software Foundation |
Copyright (C) 2002, 2003 Free Software Foundation |
3 |
|
|
4 |
This program is free software; you can redistribute it and/or modify |
GNU Radius is free software; you can redistribute it and/or modify |
5 |
it under the terms of the GNU General Public License as published by |
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 |
the Free Software Foundation; either version 2 of the License, or |
7 |
(at your option) any later version. |
(at your option) any later version. |
8 |
|
|
9 |
This program is distributed in the hope that it will be useful, |
GNU Radius is distributed in the hope that it will be useful, |
10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 |
GNU General Public License for more details. |
GNU General Public License for more details. |
13 |
|
|
14 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
15 |
along with this program; if not, write to the Free Software |
along with GNU Radius; if not, write to the Free Software |
16 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
17 |
MA 02111-1307, USA. */ |
MA 02111-1307, USA. */ |
18 |
|
|
24 |
#include <argcv.h> |
#include <argcv.h> |
25 |
#include <radius.h> |
#include <radius.h> |
26 |
#include <envar.h> |
#include <envar.h> |
27 |
#include <slist.h> |
#include <list.h> |
28 |
|
|
29 |
static REALM *realms; |
static LIST /* of REALM */ *realms; |
30 |
|
|
31 |
struct _parse_data { |
struct _parse_data { |
32 |
int (*fun)(); |
int (*fun)(); |
36 |
}; |
}; |
37 |
|
|
38 |
int |
int |
39 |
_parse_server(argc, argv, pd, np, srv) |
_parse_server(int argc, char **argv, struct _parse_data *pd, int *np, |
40 |
int argc; |
RADIUS_SERVER *srv) |
|
char **argv; |
|
|
struct _parse_data *pd; |
|
|
int *np; |
|
|
RADIUS_SERVER *srv; |
|
41 |
{ |
{ |
42 |
memset(srv, 0, sizeof(*srv)); |
memset(srv, 0, sizeof(*srv)); |
43 |
srv->name = argv[*np]; |
srv->name = argv[*np]; |
65 |
} |
} |
66 |
|
|
67 |
int |
int |
68 |
_parse_server_list(srvlist, str, pd) |
_parse_server_list(RADIUS_SERVER_QUEUE *qp, char *str, struct _parse_data *pd) |
|
RADIUS_SERVER **srvlist; |
|
|
char *str; |
|
|
struct _parse_data *pd; |
|
69 |
{ |
{ |
70 |
int i, argc; |
int i, argc; |
71 |
char **argv; |
char **argv; |
76 |
for (i = 0; i < argc; i++) { |
for (i = 0; i < argc; i++) { |
77 |
RADIUS_SERVER srv; |
RADIUS_SERVER srv; |
78 |
if (_parse_server(argc, argv, pd, &i, &srv) == 0) |
if (_parse_server(argc, argv, pd, &i, &srv) == 0) |
79 |
*srvlist = rad_clt_append_server(*srvlist, |
rad_clt_append_server(qp, rad_clt_alloc_server(&srv)); |
|
rad_clt_alloc_server(&srv)); |
|
80 |
|
|
81 |
if (i < argc && argv[i][0] != ',') { |
if (i < argc && argv[i][0] != ',') { |
82 |
radlog(L_ERR, |
radlog(L_ERR, |
83 |
"%s:%d: expected , but found %s", |
_("%s:%d: expected , but found %s"), |
84 |
pd->file, pd->line, argv[i]); |
pd->file, pd->line, argv[i]); |
85 |
argcv_free(argc, argv); |
argcv_free(argc, argv); |
86 |
return 1; |
return 1; |
94 |
/* read realms entry */ |
/* read realms entry */ |
95 |
/*ARGSUSED*/ |
/*ARGSUSED*/ |
96 |
int |
int |
97 |
read_realms_entry(pd, fc, fv, file, lineno) |
read_realms_entry(struct _parse_data *pd, int fc, char **fv, |
98 |
struct _parse_data *pd; |
char *file,int lineno) |
|
int fc; |
|
|
char **fv; |
|
|
char *file; |
|
|
int lineno; |
|
99 |
{ |
{ |
100 |
REALM *rp; |
REALM *rp; |
101 |
int i; |
int i; |
109 |
pd->file = file; |
pd->file = file; |
110 |
pd->line = lineno; |
pd->line = lineno; |
111 |
|
|
112 |
rp = mem_alloc(sizeof(REALM)); |
rp = emalloc(sizeof(REALM)); |
113 |
rp->queue = NULL; |
rp->queue = NULL; |
114 |
if (strcmp(fv[1], "LOCAL") == 0) { |
if (strcmp(fv[1], "LOCAL") == 0) { |
115 |
i = 2; |
i = 2; |
116 |
} else { |
} else { |
117 |
RADIUS_SERVER *server = NULL; |
rp->queue = rad_clt_create_queue(0, 0, 0); |
118 |
i = 0; |
i = 0; |
119 |
do { |
do { |
120 |
if (_parse_server_list(&server, fv[++i], pd)) { |
if (_parse_server_list(rp->queue, fv[++i], pd)) { |
121 |
rad_clt_clear_server_list(server); |
rad_clt_clear_server_list(rp->queue); |
|
server = NULL; |
|
122 |
break; |
break; |
123 |
} |
} |
124 |
} while (fv[i][strlen(fv[i])-1] == ',') ; |
} while (fv[i][strlen(fv[i])-1] == ',') ; |
125 |
i++; |
i++; |
126 |
|
|
127 |
if (!server) { |
if (list_count(rp->queue->servers) == 0) { |
128 |
radlog(L_ERR, |
radlog(L_ERR, |
129 |
"%s:%d: cannot parse", |
"%s:%d: cannot parse", |
130 |
file, lineno); |
file, lineno); |
131 |
|
rad_clt_destroy_queue(rp->queue); |
132 |
mem_free(rp); |
mem_free(rp); |
133 |
return 0; |
return 0; |
134 |
} |
} |
|
rp->queue = rad_clt_create_queue(0, 0, 0); |
|
|
rp->queue->first_server = server; |
|
135 |
} |
} |
136 |
|
|
137 |
STRING_COPY(rp->realm, fv[0]); |
STRING_COPY(rp->realm, fv[0]); |
152 |
rp->queue->retries = envar_lookup_int(args, |
rp->queue->retries = envar_lookup_int(args, |
153 |
"retries", 1); |
"retries", 1); |
154 |
} |
} |
155 |
envar_free_list(args); |
envar_free_list(&args); |
156 |
} |
} |
157 |
rp->next = realms; |
if (!realms) |
158 |
realms = rp; |
realms = list_create(); |
159 |
|
list_prepend(realms, rp); |
160 |
return 0; |
return 0; |
161 |
} |
} |
162 |
|
|
163 |
static void |
static int |
164 |
_realm_mem_free(r) |
_realm_mem_free(void *item, void *data ARG_UNUSED) |
|
REALM *r; |
|
165 |
{ |
{ |
166 |
|
REALM *r = item; |
167 |
rad_clt_destroy_queue(r->queue); |
rad_clt_destroy_queue(r->queue); |
168 |
|
efree(item); |
169 |
|
return 0; |
170 |
} |
} |
171 |
|
|
172 |
/* |
/* |
173 |
* Read the realms file. |
* Read the realms file. |
174 |
*/ |
*/ |
175 |
int |
int |
176 |
realm_read_file(file, auth_port, acct_port, set_secret) |
realm_read_file(char *file, int auth_port, int acct_port, int (*set_secret)()) |
|
char *file; |
|
|
int auth_port; |
|
|
int acct_port; |
|
|
int (*set_secret)(); |
|
177 |
{ |
{ |
178 |
struct _parse_data pd; |
struct _parse_data pd; |
179 |
|
|
180 |
free_slist((struct slist*)realms, _realm_mem_free); |
list_destroy(&realms, _realm_mem_free, NULL); |
181 |
realms = NULL; |
realms = NULL; |
182 |
pd.fun = set_secret; |
pd.fun = set_secret; |
183 |
pd.ports[PORT_AUTH] = auth_port; |
pd.ports[PORT_AUTH] = auth_port; |
190 |
|
|
191 |
/* Find a realm in the REALM list */ |
/* Find a realm in the REALM list */ |
192 |
REALM * |
REALM * |
193 |
realm_lookup_name(realm) |
realm_lookup_name(char *realm) |
|
char *realm; |
|
194 |
{ |
{ |
195 |
REALM *p; |
REALM *p; |
196 |
|
|
197 |
for (p = realms; p; p = p->next) |
for (p = list_first(realms); p; p = list_next(realms)) |
198 |
if (strcmp(p->realm, realm) == 0) |
if (strcmp(p->realm, realm) == 0) |
199 |
break; |
break; |
200 |
if (!p && strcmp(realm, "NOREALM")) { |
if (!p && strcmp(realm, "NOREALM")) { |
201 |
for (p = realms; p; p = p->next) |
for (p = list_first(realms); p; p = list_next(realms)) |
202 |
if (strcmp(p->realm, "DEFAULT") == 0) |
if (strcmp(p->realm, "DEFAULT") == 0) |
203 |
break; |
break; |
204 |
} |
} |
206 |
} |
} |
207 |
|
|
208 |
int |
int |
209 |
realm_verify_ip(realm, ip) |
realm_verify_ip(REALM *realm, UINT4 ip) |
|
REALM *realm; |
|
|
UINT4 ip; |
|
210 |
{ |
{ |
211 |
RADIUS_SERVER *serv; |
RADIUS_SERVER *serv; |
212 |
|
|
213 |
if (!realm->queue) |
if (!realm->queue) |
214 |
return 0; |
return 0; |
215 |
for (serv = realm->queue->first_server; serv; serv = serv->next) |
for (serv = list_first(realm->queue->servers); |
216 |
if (serv->addr == ip) |
serv; |
217 |
return 1; |
serv = list_next(realm->queue->servers)) |
218 |
|
if (serv->addr == ip) |
219 |
|
return 1; |
220 |
return 0; |
return 0; |
221 |
} |
} |
222 |
|
|
223 |
REALM * |
REALM * |
224 |
realm_lookup_ip(ip) |
realm_lookup_ip(UINT4 ip) |
|
UINT4 ip; |
|
225 |
{ |
{ |
226 |
REALM *p; |
REALM *p; |
227 |
|
|
228 |
for (p = realms; p; p = p->next) |
for (p = list_first(realms); p; p = list_next(realms)) |
229 |
if (realm_verify_ip(p, ip)) |
if (realm_verify_ip(p, ip)) |
230 |
break; |
break; |
231 |
return p; |
return p; |
232 |
} |
} |
233 |
|
|
|
void |
|
|
realm_iterate(fun) |
|
|
int (*fun)(); |
|
|
{ |
|
|
REALM *p; |
|
|
|
|
|
for (p = realms; p; p = p->next) |
|
|
fun(p); |
|
|
} |
|