Massively cleaned up #include's, so they're in a consistent
[freeradius.git] / src / main / files.c
index 0057fdc..d8caf88 100644 (file)
@@ -3,34 +3,35 @@
  *
  * Version:     $Id$
  *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ * Copyright 2000,2006  The FreeRADIUS server project
+ * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
+ * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-static const char rcsid[] = "$Id$";
-
-#include       "autoconf.h"
-
-#include       <sys/stat.h>
-
-#if HAVE_NETINET_IN_H
-#include       <netinet/in.h>
-#endif
-
-#include       <stdlib.h>
-#include       <string.h>
-#include       <netdb.h>
-#include       <ctype.h>
-#include       <fcntl.h>
+#include <freeradius-devel/ident.h>
+RCSID("$Id$")
 
-#if HAVE_MALLOC_H
-#  include     <malloc.h>
-#endif
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/rad_assert.h>
 
-#include       "radiusd.h"
-#include       "modules.h"
-#include       "conffile.h"
+#include <sys/stat.h>
 
-RADCLIENT              *clients;
-REALM                  *realms;
+#include <ctype.h>
+#include <fcntl.h>
 
 /*
  *     Free a PAIR_LIST
@@ -41,8 +42,8 @@ void pairlist_free(PAIR_LIST **pl)
 
        for (p = *pl; p; p = next) {
                if (p->name) free(p->name);
-               if (p->check) pairfree(p->check);
-               if (p->reply) pairfree(p->reply);
+               if (p->check) pairfree(&p->check);
+               if (p->reply) pairfree(&p->reply);
                next = p->next;
                free(p);
        }
@@ -50,58 +51,8 @@ void pairlist_free(PAIR_LIST **pl)
 }
 
 
-/*
- *     Fixup a check line.
- *     If Password or Crypt-Password is set, but there is no
- *     Auth-Type, add one (kludge!).
- */
-static void auth_type_fixup(VALUE_PAIR *check)
-{
-       VALUE_PAIR      *vp;
-       VALUE_PAIR      *c = NULL;
-       int             n = 0;
-
-       /*
-        *      See if a password is present. Return right away
-        *      if we see Auth-Type.
-        */
-       for (vp = check; vp; vp = vp->next) {
-               if (vp->attribute == PW_AUTHTYPE)
-                       return;
-               if (vp->attribute == PW_PASSWORD) {
-                       c = vp;
-                       n = PW_AUTHTYPE_LOCAL;
-               }
-               if (vp->attribute == PW_CRYPT_PASSWORD) {
-                       c = vp;
-                       n = PW_AUTHTYPE_CRYPT;
-               }
-       }
-
-       if (c == NULL)
-               return;
-
-       /*
-        *      Add an Auth-Type attribute.
-        *      FIXME: put Auth-Type _first_ (doesn't matter now,
-        *      might matter some day).
-        *      
-        */
-       if ((vp = paircreate(PW_AUTHTYPE, PW_TYPE_INTEGER)) == NULL) {
-               radlog(L_CONS|L_ERR, "no memory");
-               exit(1);
-       }
-       vp->lvalue = n;
-       vp->operator = T_OP_ADD;
-
-       vp->next = c->next;
-       c->next = vp;
-
-}
-
-
-#define FIND_MODE_NAME 0
-#define FIND_MODE_REPLY        1
+#define FIND_MODE_NAME  0
+#define FIND_MODE_REPLY 1
 
 /*
  *     Read the users, huntgroups or hints file.
@@ -109,27 +60,29 @@ static void auth_type_fixup(VALUE_PAIR *check)
  */
 int pairlist_read(const char *file, PAIR_LIST **list, int complain)
 {
-       FILE            *fp;
-       int             mode = FIND_MODE_NAME;
-       char            entry[256];
-       char            buffer[256];
-       char            *ptr, *s;
-       VALUE_PAIR      *check_tmp;
-       VALUE_PAIR      *reply_tmp;
-       PAIR_LIST       *pl = NULL, *last = NULL, *t;
-       int             lineno = 0;
-       int             old_lineno = 0;
-       int             parsecode;
-       char            newfile[8192];
+       FILE *fp;
+       int mode = FIND_MODE_NAME;
+       char entry[256];
+       char buffer[8192];
+       char *ptr, *s;
+       VALUE_PAIR *check_tmp;
+       VALUE_PAIR *reply_tmp;
+       PAIR_LIST *pl = NULL, *t;
+       PAIR_LIST **last = &pl;
+       int lineno = 0;
+       int old_lineno = 0;
+       LRAD_TOKEN parsecode;
+       char newfile[8192];
 
        /*
         *      Open the file.  The error message should be a little
         *      more useful...
         */
        if ((fp = fopen(file, "r")) == NULL) {
-               if (!complain) return -1;
+               if (!complain)
+                       return -1;
                radlog(L_CONS|L_ERR, "Couldn't open %s for reading: %s",
-                   file, strerror(errno));
+                               file, strerror(errno));
                return -1;
        }
 
@@ -139,22 +92,36 @@ int pairlist_read(const char *file, PAIR_LIST **list, int complain)
         */
        while(fgets(buffer, sizeof(buffer), fp) != NULL) {
                lineno++;
-               if (strchr(buffer, '\n') == NULL) {
+               if (!feof(fp) && (strchr(buffer, '\n') == NULL)) {
                        radlog(L_ERR, "%s[%d]: line too long", file, lineno);
                        pairlist_free(&pl);
                        return -1;
                }
                if (buffer[0] == '#' || buffer[0] == '\n') continue;
+
+               /*
+                *      If the line contains nothing but whitespace,
+                *      ignore it.
+                */
+               ptr = buffer;
+               while ((ptr[0] == ' ') ||
+                      (ptr[0] == '\t') ||
+                      (ptr[0] == '\r') ||
+                      (ptr[0] == '\n')) {
+                       ptr++;
+               }
+               if (ptr[0] == '\0') continue;
+
 parse_again:
                if(mode == FIND_MODE_NAME) {
                        /*
                         *      Find the entry starting with the users name
                         */
-                       if (isspace(buffer[0]))  {
+                       if (isspace((int) buffer[0]))  {
                                if (parsecode != T_EOL) {
                                        radlog(L_ERR|L_CONS,
-                                           "%s[%d]: Unexpected trailing comma for entry %s",
-                                           file, lineno, entry);
+                                              "%s[%d]: Unexpected trailing comma for entry %s",
+                                              file, lineno, entry);
                                        fclose(fp);
                                        return -1;
                                }
@@ -169,10 +136,10 @@ parse_again:
                         *      $INCLUDE filename
                         */
                        if (strcasecmp(entry, "$include") == 0) {
-                               while(isspace(*ptr))
+                               while(isspace((int) *ptr))
                                        ptr++;
                                s = ptr;
-                               while (!isspace(*ptr))
+                               while (!isspace((int) *ptr))
                                        ptr++;
                                *ptr = 0;
 
@@ -185,7 +152,7 @@ parse_again:
                                 *      file.
                                 */
                                if (*s != '/') {
-                                       strNcpy(newfile, file,
+                                       strlcpy(newfile, file,
                                                sizeof(newfile));
                                        ptr = strrchr(newfile, '/');
                                        strcpy(ptr + 1, s);
@@ -196,18 +163,21 @@ parse_again:
                                if (pairlist_read(s, &t, 0) != 0) {
                                        pairlist_free(&pl);
                                        radlog(L_ERR|L_CONS,
-                                           "%s[%d]: Could not open included file %s: %s",
-                                           file, lineno, s, strerror(errno));
+                                              "%s[%d]: Could not open included file %s: %s",
+                                              file, lineno, s, strerror(errno));
                                        fclose(fp);
                                return -1;
                                }
-                               if (last)
-                                       last->next = t;
-                               else
-                                       pl = t;
-                               last = t;
-                               while (last && last->next)
-                                       last = last->next;
+                               *last = t;
+
+                               /*
+                                *      t may be NULL, it may have one
+                                *      entry, or it may be a linked list
+                                *      of entries.  Go to the end of the
+                                *      list.
+                                */
+                               while (*last)
+                                       last = &((*last)->next);
                                continue;
                        }
 
@@ -218,7 +188,7 @@ parse_again:
                        reply_tmp = NULL;
                        old_lineno = lineno;
                        parsecode = userparse(ptr, &check_tmp);
-                       if (parsecode < 0) {
+                       if (parsecode == T_OP_INVALID) {
                                pairlist_free(&pl);
                                radlog(L_ERR|L_CONS,
                                "%s[%d]: Parse error (check) for entry %s: %s",
@@ -227,8 +197,8 @@ parse_again:
                                return -1;
                        } else if (parsecode == T_COMMA) {
                                radlog(L_ERR|L_CONS,
-                                   "%s[%d]: Unexpected trailing comma in check item list for entry %s",
-                                   file, lineno, entry);
+                                      "%s[%d]: Unexpected trailing comma in check item list for entry %s",
+                                      file, lineno, entry);
                                fclose(fp);
                                return -1;
                        }
@@ -239,8 +209,8 @@ parse_again:
                        if(*buffer == ' ' || *buffer == '\t') {
                                if (parsecode != T_COMMA) {
                                        radlog(L_ERR|L_CONS,
-                               "%s[%d]: Syntax error: Previous line is missing a trailing comma for entry %s",
-                                               file, lineno, entry);
+                                              "%s[%d]: Syntax error: Previous line is missing a trailing comma for entry %s",
+                                              file, lineno, entry);
                                        fclose(fp);
                                        return -1;
                                }
@@ -249,11 +219,12 @@ parse_again:
                                 *      Parse the reply values
                                 */
                                parsecode = userparse(buffer, &reply_tmp);
-                               if (parsecode < 0) {
+                               /* valid tokens are 1 or greater */
+                               if (parsecode < 1) {
                                        pairlist_free(&pl);
                                        radlog(L_ERR|L_CONS,
-                               "%s[%d]: Parse error (reply) for entry %s: %s",
-                                           file, lineno, entry, librad_errstr);
+                                              "%s[%d]: Parse error (reply) for entry %s: %s",
+                                              file, lineno, entry, librad_errstr);
                                        fclose(fp);
                                        return -1;
                                }
@@ -262,11 +233,8 @@ parse_again:
                                /*
                                 *      Done with this entry...
                                 */
-                               if ((t = malloc(sizeof(PAIR_LIST))) == NULL) {
-                                       perror(progname);
-                                       exit(1);
-                               }
-                               auth_type_fixup(check_tmp);
+                               t = rad_malloc(sizeof(PAIR_LIST));
+
                                memset(t, 0, sizeof(*t));
                                t->name = strdup(entry);
                                t->check = check_tmp;
@@ -274,11 +242,9 @@ parse_again:
                                t->lineno = old_lineno;
                                check_tmp = NULL;
                                reply_tmp = NULL;
-                               if (last)
-                                       last->next = t;
-                               else
-                                       pl = t;
-                               last = t;
+
+                               *last = t;
+                               last = &(t->next);
 
                                mode = FIND_MODE_NAME;
                                if (buffer[0] != 0)
@@ -326,383 +292,3 @@ static void debug_pair_list(PAIR_LIST *pl)
        }
 }
 #endif
-
-/*
- *     Free a RADCLIENT list.
- */
-static void clients_free(RADCLIENT *cl)
-{
-       RADCLIENT *next;
-
-       while(cl) {
-               next = cl->next;
-               free(cl);
-               cl = next;
-       }
-}
-
-
-/*
- *     Read the clients file.
- */
-static int read_clients_file(const char *file)
-{
-       FILE    *fp;
-       RADCLIENT       *c;
-       char    buffer[256];
-       char    hostnm[256];
-       char    secret[256];
-       char    shortnm[256];
-       int     lineno = 0;
-       char    *p;
-
-       clients_free(clients);
-       clients = NULL;
-
-       if ((fp = fopen(file, "r")) == NULL) {
-               radlog(L_CONS|L_ERR, "cannot open %s", file);
-               return -1;
-       }
-       while(fgets(buffer, 256, fp) != NULL) {
-               lineno++;
-               if (strchr(buffer, '\n') == NULL) {
-                       radlog(L_ERR, "%s[%d]: line too long", file, lineno);
-                       return -1;
-               }
-               if (buffer[0] == '#' || buffer[0] == '\n')
-                       continue;
-
-               p = buffer;
-
-               if (!getword(&p, hostnm, sizeof(hostnm)) ||
-                   !getword(&p, secret, sizeof(secret))) {
-                       radlog(L_ERR, "%s[%d]: unexpected end of line",
-                           file, lineno);
-                       return -1;
-               }
-
-               (void)getword(&p, shortnm, sizeof(shortnm));
-
-               /*
-                *      Double-check lengths to be sure they're sane
-                */
-               if (strlen(hostnm) >= sizeof(c->longname)) {
-                       radlog(L_ERR, "%s[%d]: host name of length %d is greater than the allowed maximum of %d.",
-                           file, lineno,
-                           strlen(hostnm), sizeof(c->longname) - 1);
-                       return -1;
-               }
-               if (strlen(secret) >= sizeof(c->secret)) {
-                       radlog(L_ERR, "%s[%d]: secret of length %d is greater than the allowed maximum of %d.",
-                           file, lineno,
-                           strlen(secret), sizeof(c->secret) - 1);
-                       return -1;
-               }
-               if (strlen(shortnm) > sizeof(c->shortname)) {
-                       radlog(L_ERR, "%s[%d]: short name of length %d is greater than the allowed maximum of %d.",
-                           file, lineno,
-                           strlen(shortnm), sizeof(c->shortname) - 1);
-                       return -1;
-               }
-               
-               /*
-                *      It should be OK now, let's create the buffer.
-                */
-               if ((c = malloc(sizeof(RADCLIENT))) == NULL) {
-                       radlog(L_CONS|L_ERR, "%s[%d]: out of memory",
-                               file, lineno);
-                       return -1;
-               }
-
-               c->ipaddr = ip_getaddr(hostnm);
-               if (c->ipaddr == 0) {
-                       radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
-                           file, lineno, hostnm);
-                       return -1;
-               }
-               strcpy((char *)c->secret, secret);
-               strcpy(c->shortname, shortnm);
-               ip_hostname(c->longname, sizeof(c->longname), c->ipaddr);
-
-               c->next = clients;
-               clients = c;
-       }
-       fclose(fp);
-
-       return 0;
-}
-
-
-/*
- *     Find a client in the RADCLIENTS list.
- */
-RADCLIENT *client_find(uint32_t ipaddr)
-{
-       RADCLIENT *cl;
-
-       for(cl = clients; cl; cl = cl->next)
-               if (ipaddr == cl->ipaddr)
-                       break;
-
-       return cl;
-}
-
-
-/*
- *     Find the name of a client (prefer short name).
- */
-char *client_name(uint32_t ipaddr)
-{
-       RADCLIENT *cl;
-
-       if ((cl = client_find(ipaddr)) != NULL) {
-               if (cl->shortname[0])
-                       return cl->shortname;
-               else
-                       return cl->longname;
-       }
-
-       /*
-        *      FIXME!
-        *
-        *      We should NEVER reach this piece of code, as we should
-        *      NEVER be looking up client names for clients we don't know!
-        */
-       return NULL;
-}
-
-#ifndef BUILDDBM /* HACK HACK */
-
-/*
- *     Free a REALM list.
- */
-static void realm_free(REALM *cl)
-{
-       REALM *next;
-
-       while(cl) {
-               next = cl->next;
-               free(cl);
-               cl = next;
-       }
-}
-
-/*
- *     Read the realms file.
- */
-static int read_realms_file(const char *file)
-{
-       FILE    *fp;
-       char    buffer[256];
-       char    realm[256];
-       char    hostnm[256];
-       char    opts[256];
-       char    *s, *p;
-       int     lineno = 0;
-       REALM   *c;
-       RADCLIENT *client;
-
-       realm_free(realms);
-       realms = NULL;
-
-       if ((fp = fopen(file, "r")) == NULL) {
-#if 1 /* For now - realms file is not obligatory */
-               return 0;
-#else
-               radlog(L_CONS|L_ERR, "cannot open %s", file);
-               return -1;
-#endif
-       }
-       while(fgets(buffer, 256, fp) != NULL) {
-               lineno++;
-               if (strchr(buffer, '\n') == NULL) {
-                       radlog(L_ERR, "%s[%d]: line too long", file, lineno);
-                       return -1;
-               }
-               if (buffer[0] == '#' || buffer[0] == '\n')
-                       continue;
-               p = buffer;
-               if (!getword(&p, realm, sizeof(realm)) ||
-                   !getword(&p, hostnm, sizeof(hostnm))) {
-                       radlog(L_ERR, "%s[%d]: syntax error", file, lineno);
-                       continue;
-               }
-
-               if ((c = malloc(sizeof(REALM))) == NULL) {
-                       radlog(L_CONS|L_ERR, "%s[%d]: out of memory",
-                               file, lineno);
-                       return -1;
-               }
-               memset(c, 0, sizeof(REALM));
-
-               if ((s = strchr(hostnm, ':')) != NULL) {
-                       *s++ = 0;
-                       c->auth_port = atoi(s);
-                       c->acct_port = c->auth_port + 1;
-               } else {
-                       c->auth_port = auth_port;
-                       c->acct_port = acct_port;
-               }
-
-               if (strcmp(hostnm, "LOCAL") == 0) {
-                       c->ipaddr = htonl(INADDR_LOOPBACK);
-               } else {
-                       c->ipaddr = ip_getaddr(hostnm);
-               }
-
-               if (c->ipaddr == 0) {
-                       radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
-                           file, lineno, hostnm);
-                       return -1;
-               }
-
-               /*
-                *      Find the remote server in the "clients" list.
-                *      If we can't find it, there's a big problem...
-                */
-               client = client_find(c->ipaddr);
-               if (client == NULL) {
-                       radlog(L_CONS|L_ERR, "%s[%d]: Cannot find 'clients' file entry of remote server %s for realm \"%s\"",
-                           file, lineno, hostnm, realm);
-                       return -1;
-               }
-               memcpy(c->secret, client->secret, sizeof(c->secret));
-
-               /*
-                *      Double-check lengths to be sure they're sane
-                */
-               if (strlen(hostnm) >= sizeof(c->server)) {
-                       radlog(L_ERR, "%s[%d]: server name of length %d is greater than the allowed maximum of %d.",
-                           file, lineno,
-                           strlen(hostnm), sizeof(c->server) - 1);
-                       return -1;
-               }
-               if (strlen(realm) > sizeof(c->realm)) {
-                       radlog(L_ERR, "%s[%d]: realm of length %d is greater than the allowed maximum of %d.",
-                           file, lineno,
-                           strlen(realm), sizeof(c->realm) - 1);
-                       return -1;
-               }
-
-               /*
-                *      OK, they're sane, copy them over.
-                */
-               strcpy(c->realm, realm);
-               strcpy(c->server, hostnm);
-               c->striprealm = TRUE;
-
-               while (getword(&p, opts, sizeof(opts))) {
-                       if (strcmp(opts, "nostrip") == 0)
-                               c->striprealm = FALSE;
-                       if (strstr(opts, "noacct") != NULL)
-                               c->acct_port = 0;
-                       if (strstr(opts, "trusted") != NULL)
-                               c->trusted = 1;
-                       if (strstr(opts, "notsuffix") != NULL)
-                               c->notsuffix = 1;
-               }
-
-               c->next = realms;
-               realms = c;
-       }
-       fclose(fp);
-
-       return 0;
-}
-#endif /* BUILDDBM */
-
-/*
- *     Find a realm in the REALM list.
- */
-REALM *realm_find(const char *realm)
-{
-       REALM *cl;
-
-       /*
-        *      If we're passed a NULL realm pointer,
-        *      then look for a "NULL" realm string.
-        */
-       if (realm == NULL) {
-               realm = "NULL";
-       }
-
-       for(cl = realms; cl; cl = cl->next)
-               if (strcmp(cl->realm, realm) == 0)
-                       break;
-       if (cl) return cl;
-       for(cl = realms; cl; cl = cl->next)
-               if (strcmp(cl->realm, "DEFAULT") == 0)
-                       break;
-       return cl;
-}
-
-
-/*
- *     Find a realm for a proxy reply by proxy's IP
- */
-REALM *realm_findbyaddr(uint32_t ipaddr)
-{
-       REALM *cl;
-
-       for(cl = realms; cl; cl = cl->next)
-               if (ipaddr == cl->ipaddr)
-                       break;
-
-       return cl;
-}
-
-
-#ifndef BUILDDBM /* HACK HACK */
-
-/*
- *     (Re-) read the configuration files.
- */
-int read_config_files()
-{
-       char buffer[256];
-
-        /* Initialize the dictionary */
-       DEBUG2("read_config_files:  reading dictionary");
-       if (dict_init(radius_dir, RADIUS_DICTIONARY) != 0) {
-               radlog(L_ERR|L_CONS, "Errors reading dictionary: %s",
-                   librad_errstr);
-               return -1;
-       }
-
-       sprintf(buffer, "%.200s/%.50s", radius_dir, RADIUS_CLIENTS);
-       DEBUG2("read_config_files:  reading clients");
-       if (read_clients_file(buffer) < 0) {
-               radlog(L_ERR|L_CONS, "Errors reading clients");
-               return -1;
-       }
-
-       sprintf(buffer, "%.200s/%.50s", radius_dir, RADIUS_REALMS);
-       DEBUG2("read_config_files:  reading realms");
-       if (read_realms_file(buffer) < 0) {
-               radlog(L_ERR|L_CONS, "Errors reading realms");
-               return -1;
-       }
-
-       DEBUG2("read_config_files:  reading radiusd.conf");
-       if (read_radius_conf_file() < 0) {
-               radlog(L_ERR|L_CONS, "Errors reading radiusd.conf");
-               return -1;
-       }
-
-       sprintf(buffer, "%.200s/%.50s", radius_dir, RADIUS_NASLIST);
-       DEBUG2("read_config_files:  reading naslist");
-       if (read_naslist_file(buffer) < 0) {
-               radlog(L_ERR|L_CONS, "Errors reading naslist");
-               return -1;
-       }
-
-       DEBUG2("read_config_files:  entering modules setup");
-       if (setup_modules() < 0) {
-               radlog(L_ERR|L_CONS, "Errors setting up modules");
-               return -1;
-       }
-
-       return 0;
-}
-
-#endif