2 * files.c Read config files into memory.
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Copyright 2000 The FreeRADIUS server project
21 * Copyright 2000 Miquel van Smoorenburg <miquels@cistron.nl>
22 * Copyright 2000 Alan DeKok <aland@ox.org>
25 static const char rcsid[] = "$Id$";
28 #include "libradius.h"
33 # include <netinet/in.h>
48 * Free a RADCLIENT list.
50 static void clients_free(RADCLIENT *cl)
63 * Read the clients file.
65 int read_clients_file(const char *file)
77 clients_free(clients);
80 if ((fp = fopen(file, "r")) == NULL) {
81 /* The clients file is no longer required. All configuration
82 information is read from radiusd.conf and friends. If
83 clients exists it will be used, but if it doesn't no harm
88 while(fgets(buffer, 256, fp) != NULL) {
90 if (strchr(buffer, '\n') == NULL) {
91 radlog(L_ERR, "%s[%d]: line too long", file, lineno);
100 ((*p == ' ') || (*p == '\t')))
104 * Skip comments and blank lines.
106 if ((*p == '#') || (*p == '\n') || (*p == '\r'))
109 if (!getword(&p, hostnm, sizeof(hostnm)) ||
110 !getword(&p, secret, sizeof(secret))) {
111 radlog(L_ERR, "%s[%d]: unexpected end of line",
116 (void)getword(&p, shortnm, sizeof(shortnm));
119 * Look for a mask in the hostname
121 p = strchr(hostnm, '/');
130 mask_length = atoi(p);
131 if ((mask_length <= 0) || (mask_length > 32)) {
132 radlog(L_ERR, "%s[%d]: Invalid value '%s' for IP network mask.",
138 for (i = 1; i < mask_length; i++) {
144 * Double-check lengths to be sure they're sane
146 if (strlen(hostnm) >= sizeof(c->longname)) {
147 radlog(L_ERR, "%s[%d]: host name of length %d is greater than the allowed maximum of %d.",
149 strlen(hostnm), sizeof(c->longname) - 1);
152 if (strlen(secret) >= sizeof(c->secret)) {
153 radlog(L_ERR, "%s[%d]: secret of length %d is greater than the allowed maximum of %d.",
155 strlen(secret), sizeof(c->secret) - 1);
158 if (strlen(shortnm) > sizeof(c->shortname)) {
159 radlog(L_ERR, "%s[%d]: short name of length %d is greater than the allowed maximum of %d.",
161 strlen(shortnm), sizeof(c->shortname) - 1);
166 * It should be OK now, let's create the buffer.
168 c = rad_malloc(sizeof(RADCLIENT));
170 c->ipaddr = ip_getaddr(hostnm);
171 if (c->ipaddr == INADDR_NONE) {
172 radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
173 file, lineno, hostnm);
176 c->netmask = htonl(mask);
179 strcpy((char *)c->secret, secret);
180 strcpy(c->shortname, shortnm);
183 * Only do DNS lookups for machines. Just print
184 * the network as the long name.
186 if (c->netmask == ~0) {
187 ip_hostname(c->longname, sizeof(c->longname), c->ipaddr);
189 hostnm[strlen(hostnm)] = '/';
190 strNcpy(c->longname, hostnm, sizeof(c->longname));
203 * Find a client in the RADCLIENTS list.
205 RADCLIENT *client_find(uint32_t ipaddr)
208 RADCLIENT *match = NULL;
210 for(cl = clients; cl; cl = cl->next) {
211 if ((ipaddr & cl->netmask) == cl->ipaddr) {
213 (ntohl(cl->netmask) > ntohl(match->netmask))) {
223 * Walk the RADCLIENT list displaying the clients. This function
224 * is for debugging purposes.
226 void client_walk(void)
229 char host_ipaddr[16];
231 for (cl = clients; cl != NULL; cl = cl->next)
232 radlog(L_ERR, "client: client_walk: %s\n",
233 ip_ntoa(host_ipaddr, cl->ipaddr));
237 * Find the name of a client (prefer short name).
239 const char *client_name(uint32_t ipaddr)
243 if ((cl = client_find(ipaddr)) != NULL) {
244 if (cl->shortname[0])
245 return cl->shortname;
251 * We should NEVER reach this piece of code, as we should
252 * NEVER be looking up client names for clients we don't know!
254 radlog(L_ERR, "ERROR! Unreachable code reached, at %s:%d", __FILE__, __LINE__);
256 return "UNKNOWN-CLIENT";