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) {
177 radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
178 file, lineno, hostnm);
181 c->netmask = htonl(mask);
182 c->ipaddr &= c->netmask; /* addr & mask are in network order */
184 strcpy((char *)c->secret, secret);
185 strcpy(c->shortname, shortnm);
188 * Only do DNS lookups for machines. Just print
189 * the network as the long name.
193 ip_hostname(c->longname, sizeof(c->longname), c->ipaddr);
196 * Pull information over from the NAS.
198 nas = nas_find(c->ipaddr);
201 * No short name in the 'clients' file,
202 * try copying one over from the
205 if (c->shortname[0] == '\0') {
206 strcpy(c->shortname, nas->shortname);
210 * Copy the nastype over, too.
212 strcpy(c->nastype, nas->nastype);
215 hostnm[strlen(hostnm)] = '/';
216 strNcpy(c->longname, hostnm, sizeof(c->longname));
219 c->next = mainconfig.clients;
220 mainconfig.clients = c;
225 radlog(L_INFO, "Using deprecated clients file. Support for this will go away soon.");
233 * Find a client in the RADCLIENTS list.
235 RADCLIENT *client_find(uint32_t ipaddr)
238 RADCLIENT *match = NULL;
240 for (cl = mainconfig.clients; cl; cl = cl->next) {
241 if ((ipaddr & cl->netmask) == cl->ipaddr) {
243 (ntohl(cl->netmask) > ntohl(match->netmask))) {
253 * Walk the RADCLIENT list displaying the clients. This function
254 * is for debugging purposes.
256 void client_walk(void)
259 char host_ipaddr[16];
261 for (cl = mainconfig.clients; cl != NULL; cl = cl->next)
262 radlog(L_ERR, "client: client_walk: %s\n",
263 ip_ntoa(host_ipaddr, cl->ipaddr));
267 * Find the name of a client (prefer short name).
269 const char *client_name(uint32_t ipaddr)
271 /* We don't call this unless we should know about the client. */
273 char host_ipaddr[16];
275 if ((cl = client_find(ipaddr)) != NULL) {
276 if (cl->shortname[0])
277 return cl->shortname;
283 * this isn't normally reachable, but if a loggable event happens just
284 * after a client list change and a HUP, then we may not know this
285 * information any more.
287 * If you see lots of these, then there's something wrong.
289 radlog(L_ERR, "Trying to look up name of unknown client %s.\n",
290 ip_ntoa(host_ipaddr, ipaddr));
292 return "UNKNOWN-CLIENT";