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)
75 clients_free(mainconfig.clients);
76 mainconfig.clients = NULL;
78 if ((fp = fopen(file, "r")) == NULL) {
79 /* The clients file is no longer required. All configuration
80 information is read from radiusd.conf and friends. If
81 clients exists it will be used, but if it doesn't no harm
85 radlog(L_INFO, "Using deprecated clients file. Support for this will go away soon.");
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.",
137 for (i = 1; i < mask_length; i++) {
143 * Double-check lengths to be sure they're sane
145 if (strlen(hostnm) >= sizeof(c->longname)) {
146 radlog(L_ERR, "%s[%d]: host name of length %d is greater than the allowed maximum of %d.",
148 (int) strlen(hostnm),
149 (int) 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 (int) strlen(secret),
156 (int) sizeof(c->secret) - 1);
159 if (strlen(shortnm) > sizeof(c->shortname)) {
160 radlog(L_ERR, "%s[%d]: short name of length %d is greater than the allowed maximum of %d.",
162 (int) strlen(shortnm),
163 (int) sizeof(c->shortname) - 1);
168 * It should be OK now, let's create the buffer.
170 c = rad_malloc(sizeof(RADCLIENT));
171 memset(c, 0, sizeof(*c));
173 c->ipaddr = ip_getaddr(hostnm);
174 if (c->ipaddr == INADDR_NONE) {
175 radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
176 file, lineno, hostnm);
179 c->netmask = htonl(mask);
180 c->ipaddr &= c->netmask; /* addr & mask are in network order */
182 strcpy((char *)c->secret, secret);
183 strcpy(c->shortname, shortnm);
186 * Only do DNS lookups for machines. Just print
187 * the network as the long name.
191 ip_hostname(c->longname, sizeof(c->longname), c->ipaddr);
194 * Pull information over from the NAS.
196 nas = nas_find(c->ipaddr);
199 * No short name in the 'clients' file,
200 * try copying one over from the
203 if (c->shortname[0] == '\0') {
204 strcpy(c->shortname, nas->shortname);
208 * Copy the nastype over, too.
210 strcpy(c->nastype, nas->nastype);
213 hostnm[strlen(hostnm)] = '/';
214 strNcpy(c->longname, hostnm, sizeof(c->longname));
217 c->next = mainconfig.clients;
218 mainconfig.clients = c;
227 * Find a client in the RADCLIENTS list.
229 RADCLIENT *client_find(uint32_t ipaddr)
232 RADCLIENT *match = NULL;
234 for (cl = mainconfig.clients; cl; cl = cl->next) {
235 if ((ipaddr & cl->netmask) == cl->ipaddr) {
237 (ntohl(cl->netmask) > ntohl(match->netmask))) {
247 * Walk the RADCLIENT list displaying the clients. This function
248 * is for debugging purposes.
250 void client_walk(void)
253 char host_ipaddr[16];
255 for (cl = mainconfig.clients; cl != NULL; cl = cl->next)
256 radlog(L_ERR, "client: client_walk: %s\n",
257 ip_ntoa(host_ipaddr, cl->ipaddr));
261 * Find the name of a client (prefer short name).
263 const char *client_name(uint32_t ipaddr)
265 /* We don't call this unless we should know about the client. */
267 char host_ipaddr[16];
269 if ((cl = client_find(ipaddr)) != NULL) {
270 if (cl->shortname[0])
271 return cl->shortname;
277 * this isn't normally reachable, but if a loggable event happens just
278 * after a client list change and a HUP, then we may not know this
279 * information any more.
281 * If you see lots of these, then there's something wrong.
283 radlog(L_ERR, "Trying to look up name of unknown client %s.\n",
284 ip_ntoa(host_ipaddr, ipaddr));
286 return "UNKNOWN-CLIENT";