2 * files.c Read config files into memory.
4 * Version: @(#)files.c 2.52 10-Aug-1999 miquels@cistron.nl
9 "@(#)files.c 2.52 Copyright 1999 Cistron Internet Services B.V.";
13 #include <sys/types.h>
14 #include <sys/socket.h>
17 #include <netinet/in.h>
41 void pairlist_free(PAIR_LIST **pl)
45 for (p = *pl; p; p = next) {
46 if (p->name) free(p->name);
47 if (p->check) pairfree(p->check);
48 if (p->reply) pairfree(p->reply);
58 * If Password or Crypt-Password is set, but there is no
59 * Auth-Type, add one (kludge!).
61 static void auth_type_fixup(VALUE_PAIR *check)
68 * See if a password is present. Return right away
69 * if we see Auth-Type.
71 for (vp = check; vp; vp = vp->next) {
72 if (vp->attribute == PW_AUTHTYPE)
74 if (vp->attribute == PW_PASSWORD) {
76 n = PW_AUTHTYPE_LOCAL;
78 if (vp->attribute == PW_CRYPT_PASSWORD) {
80 n = PW_AUTHTYPE_CRYPT;
88 * Add an Auth-Type attribute.
89 * FIXME: put Auth-Type _first_ (doesn't matter now,
90 * might matter some day).
93 if ((vp = paircreate(PW_AUTHTYPE, PW_TYPE_INTEGER)) == NULL) {
94 log(L_CONS|L_ERR, "no memory");
105 #define FIND_MODE_NAME 0
106 #define FIND_MODE_REPLY 1
109 * Read the users, huntgroups or hints file.
110 * Return a PAIR_LIST.
112 PAIR_LIST *pairlist_read(char *file, int complain)
115 int mode = FIND_MODE_NAME;
119 VALUE_PAIR *check_tmp;
120 VALUE_PAIR *reply_tmp;
121 PAIR_LIST *pl = NULL, *last = NULL, *t;
128 if ((fp = fopen(file, "r")) == NULL) {
129 if (!complain) return NULL;
130 log(L_CONS|L_ERR, "Couldn't open %s for reading", file);
135 * Read the entire file into memory for speed.
137 while(fgets(buffer, sizeof(buffer), fp) != (char *)NULL) {
139 if (buffer[0] == '#' || buffer[0] == '\n') continue;
141 if(mode == FIND_MODE_NAME) {
143 * Find the entry starting with the users name
145 if (isspace(buffer[0])) continue;
148 getword(&ptr, entry, sizeof(entry));
151 * Include another file if we see
154 if (strcasecmp(entry, "$include") == 0) {
158 while (!isspace(*ptr))
161 if ((t = pairlist_read(s, 1)) == NULL)
168 while (last && last->next)
174 * Parse the check values
179 if(userparse(ptr, &check_tmp) != 0) {
181 "%s[%d]: Parse error (check) for entry %s",
182 file, lineno, entry);
186 mode = FIND_MODE_REPLY;
189 if(*buffer == ' ' || *buffer == '\t') {
191 * Parse the reply values
193 if (userparse(buffer, &reply_tmp)!=0) {
195 "%s[%d]: Parse error (reply) for entry %s",
196 file, lineno, entry);
203 * Done with this entry...
205 if ((t = malloc(sizeof(PAIR_LIST))) == NULL) {
209 auth_type_fixup(check_tmp);
210 memset(t, 0, sizeof(*t));
211 t->name = strdup(entry);
212 t->check = check_tmp;
213 t->reply = reply_tmp;
214 t->lineno = old_lineno;
223 mode = FIND_MODE_NAME;
230 * Make sure that we also read the last line of the file!
232 if (mode == FIND_MODE_REPLY) {
246 static void debug_pair_list(PAIR_LIST *pl)
251 printf("Pair list: %s\n", pl->name);
252 printf("** Check:\n");
253 for(vp = pl->check; vp; vp = vp->next) {
255 fprint_attr_val(stdout, vp);
258 printf("** Reply:\n");
259 for(vp = pl->reply; vp; vp = vp->next) {
261 fprint_attr_val(stdout, vp);
270 * Free a CLIENT list.
272 static void clients_free(CLIENT *cl)
285 * Read the clients file.
287 int read_clients_file(char *file)
298 clients_free(clients);
301 if ((fp = fopen(file, "r")) == NULL) {
302 log(L_CONS|L_ERR, "cannot open %s", file);
305 while(fgets(buffer, 256, fp) != NULL) {
307 if (buffer[0] == '#' || buffer[0] == '\n')
311 if (!getword(&p, hostnm, sizeof(hostnm)) ||
312 !getword(&p, secret, sizeof(secret))) {
313 log(L_ERR, "%s[%d]: syntax error", file, lineno);
316 (void)getword(&p, shortnm, sizeof(shortnm));
318 if ((c = malloc(sizeof(CLIENT))) == NULL) {
319 log(L_CONS|L_ERR, "%s[%d]: out of memory",
324 c->ipaddr = ip_getaddr(hostnm);
325 strcpy(c->secret, secret);
326 strcpy(c->shortname, shortnm);
327 strcpy(c->longname, ip_hostname(c->ipaddr));
339 * Find a client in the CLIENTS list.
341 CLIENT *client_find(UINT4 ipaddr)
345 for(cl = clients; cl; cl = cl->next)
346 if (ipaddr == cl->ipaddr)
354 * Find the name of a client (prefer short name).
356 char *client_name(UINT4 ipaddr)
360 if ((cl = client_find(ipaddr)) != NULL) {
361 if (cl->shortname[0])
362 return cl->shortname;
366 return ip_hostname(ipaddr);
369 #ifndef BUILDDBM /* HACK HACK */
374 static void realm_free(REALM *cl)
387 * Read the realms file.
389 int read_realms_file(char *file)
403 if ((fp = fopen(file, "r")) == NULL) {
404 #if 1 /* For now - realms file is not obligatory */
407 log(L_CONS|L_ERR, "cannot open %s", file);
411 while(fgets(buffer, 256, fp) != NULL) {
413 if (buffer[0] == '#' || buffer[0] == '\n')
416 if (!getword(&p, realm, sizeof(realm)) ||
417 !getword(&p, hostnm, sizeof(hostnm))) {
418 log(L_ERR, "%s[%d]: syntax error", file, lineno);
422 if ((c = malloc(sizeof(REALM))) == NULL) {
423 log(L_CONS|L_ERR, "%s[%d]: out of memory",
427 memset(c, 0, sizeof(REALM));
429 if ((s = strchr(hostnm, ':')) != NULL) {
431 c->auth_port = atoi(s);
432 c->acct_port = c->auth_port + 1;
434 c->auth_port = auth_port;
435 c->acct_port = acct_port;
437 if (strcmp(hostnm, "LOCAL") != 0)
438 c->ipaddr = ip_getaddr(hostnm);
439 strcpy(c->realm, realm);
440 strcpy(c->server, hostnm);
443 while (getword(&p, opts, sizeof(opts))) {
444 if (strcmp(opts, "nostrip") == 0)
446 if (strstr(opts, "noacct") != NULL)
460 * Find a realm in the REALM list.
462 REALM *realm_find(char *realm)
466 for(cl = realms; cl; cl = cl->next)
467 if (strcmp(cl->realm, realm) == 0)
470 for(cl = realms; cl; cl = cl->next)
471 if (strcmp(cl->realm, "DEFAULT") == 0)
477 #ifndef BUILDDBM /* HACK HACK */
480 * (Re-) read the configuration files.
482 int read_config_files()
486 /* Initialize the dictionary */
487 if (dict_init(radius_dir, RADIUS_DICTIONARY) != 0) {
488 log(L_ERR|L_CONS, "Errors reading dictionary");
492 sprintf(buffer, "%s/%s", radius_dir, RADIUS_MODULES);
493 if (read_modules_file(buffer) < 0) {
494 log(L_ERR|L_CONS, "Errors reading modules");
497 sprintf(buffer, "%s/%s", radius_dir, RADIUS_CLIENTS);
498 if (read_clients_file(buffer) < 0) {
499 log(L_ERR|L_CONS, "Errors reading clients");
502 sprintf(buffer, "%s/%s", radius_dir, RADIUS_NASLIST);
503 if (read_naslist_file(buffer) < 0) {
504 log(L_ERR|L_CONS, "Errors reading naslist");
507 sprintf(buffer, "%s/%s", radius_dir, RADIUS_REALMS);
508 if (read_realms_file(buffer) < 0) {
509 log(L_ERR|L_CONS, "Errors reading realms");