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"
32 #ifdef HAVE_NETINET_IN_H
33 # include <netinet/in.h>
46 * Free a RADCLIENT list.
48 void clients_free(RADCLIENT *cl)
61 * Read the clients file.
63 int read_clients_file(const char *file)
74 int got_clients = FALSE;
76 clients_free(mainconfig.clients);
77 mainconfig.clients = NULL;
79 if ((fp = fopen(file, "r")) == NULL) {
80 /* The clients file is no longer required. All configuration
81 information is read from radiusd.conf and friends. If
82 clients exists it will be used, but if it doesn't no harm
87 while(fgets(buffer, 256, fp) != NULL) {
89 if (!feof(fp) && (strchr(buffer, '\n') == NULL)) {
90 radlog(L_ERR, "%s[%d]: line too long", file, lineno);
99 ((*p == ' ') || (*p == '\t')))
103 * Skip comments and blank lines.
105 if ((*p == '#') || (*p == '\n') || (*p == '\r'))
108 if (!getword(&p, hostnm, sizeof(hostnm)) ||
109 !getword(&p, secret, sizeof(secret))) {
110 radlog(L_ERR, "%s[%d]: unexpected end of line",
115 (void)getword(&p, shortnm, sizeof(shortnm));
118 * Look for a mask in the hostname
120 p = strchr(hostnm, '/');
129 mask_length = atoi(p);
130 if ((mask_length < 0) || (mask_length > 32)) {
131 radlog(L_ERR, "%s[%d]: Invalid value '%s' for IP network mask.",
136 if (mask_length == 0) {
139 mask = ~0 << (32 - mask_length);
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 (int) strlen(hostnm),
150 (int) sizeof(c->longname) - 1);
153 if (strlen(secret) >= sizeof(c->secret)) {
154 radlog(L_ERR, "%s[%d]: secret of length %d is greater than the allowed maximum of %d.",
156 (int) strlen(secret),
157 (int) sizeof(c->secret) - 1);
160 if (strlen(shortnm) > sizeof(c->shortname)) {
161 radlog(L_ERR, "%s[%d]: short name of length %d is greater than the allowed maximum of %d.",
163 (int) strlen(shortnm),
164 (int) sizeof(c->shortname) - 1);
169 * It should be OK now, let's create the buffer.
172 c = rad_malloc(sizeof(RADCLIENT));
173 memset(c, 0, sizeof(*c));
175 c->ipaddr = ip_getaddr(hostnm);
176 if (c->ipaddr == INADDR_NONE) {
178 radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
179 file, lineno, hostnm);
182 c->netmask = htonl(mask);
183 c->ipaddr &= c->netmask; /* addr & mask are in network order */
185 strcpy((char *)c->secret, secret);
186 strcpy(c->shortname, shortnm);
189 * Only do DNS lookups for machines. Just print
190 * the network as the long name.
194 ip_hostname(c->longname, sizeof(c->longname), c->ipaddr);
197 * Pull information over from the NAS.
199 nas = nas_find(c->ipaddr);
202 * No short name in the 'clients' file,
203 * try copying one over from the
206 if (c->shortname[0] == '\0') {
207 strcpy(c->shortname, nas->shortname);
211 * Copy the nastype over, too.
213 strcpy(c->nastype, nas->nastype);
216 hostnm[strlen(hostnm)] = '/';
217 strNcpy(c->longname, hostnm, sizeof(c->longname));
220 c->next = mainconfig.clients;
221 mainconfig.clients = c;
226 radlog(L_INFO, "Using deprecated clients file. Support for this will go away soon.");
234 * Find a client in the RADCLIENTS list.
236 RADCLIENT *client_find(uint32_t ipaddr)
239 RADCLIENT *match = NULL;
241 for (cl = mainconfig.clients; cl; cl = cl->next) {
242 if ((ipaddr & cl->netmask) == cl->ipaddr) {
244 (ntohl(cl->netmask) > ntohl(match->netmask))) {
254 * Walk the RADCLIENT list displaying the clients. This function
255 * is for debugging purposes.
257 void client_walk(void)
260 char host_ipaddr[16];
262 for (cl = mainconfig.clients; cl != NULL; cl = cl->next)
263 radlog(L_ERR, "client: client_walk: %s\n",
264 ip_ntoa(host_ipaddr, cl->ipaddr));
268 * Find the name of a client (prefer short name).
270 const char *client_name(uint32_t ipaddr)
272 /* We don't call this unless we should know about the client. */
274 char host_ipaddr[16];
276 if ((cl = client_find(ipaddr)) != NULL) {
277 if (cl->shortname[0])
278 return cl->shortname;
284 * this isn't normally reachable, but if a loggable event happens just
285 * after a client list change and a HUP, then we may not know this
286 * information any more.
288 * If you see lots of these, then there's something wrong.
290 radlog(L_ERR, "Trying to look up name of unknown client %s.\n",
291 ip_ntoa(host_ipaddr, ipaddr));
293 return "UNKNOWN-CLIENT";