Massively cleaned up #include's, so they're in a consistent
[freeradius.git] / src / main / files.c
index c4970de..d8caf88 100644 (file)
  *
  *   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2000  The FreeRADIUS server project
+ * 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 <freeradius-devel/ident.h>
+RCSID("$Id$")
 
-#include "autoconf.h"
-#include "libradius.h"
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/rad_assert.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 "radiusd.h"
-
-int maximum_proxies;
-
 /*
  *     Free a PAIR_LIST
  */
@@ -61,59 +51,6 @@ void pairlist_free(PAIR_LIST **pl)
 }
 
 
-/*
- *     Fixup a check line.
- *     If User-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.
-        *      
-        */
-       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;
-       strcpy(vp->strvalue, "Local");
-
-       vp->next = *check;
-       *check = vp;
-
-       for(vp = *check; vp; vp = vp->next) {
-               DEBUG2("  auth_type_fixup: %s [%d]", vp->name, vp->attribute);
-       }
-
-}
-
-
 #define FIND_MODE_NAME  0
 #define FIND_MODE_REPLY 1
 
@@ -126,11 +63,12 @@ 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 buffer[8192];
        char *ptr, *s;
        VALUE_PAIR *check_tmp;
        VALUE_PAIR *reply_tmp;
-       PAIR_LIST *pl = NULL, *last = NULL, *t;
+       PAIR_LIST *pl = NULL, *t;
+       PAIR_LIST **last = &pl;
        int lineno = 0;
        int old_lineno = 0;
        LRAD_TOKEN parsecode;
@@ -141,7 +79,7 @@ int pairlist_read(const char *file, PAIR_LIST **list, int complain)
         *      more useful...
         */
        if ((fp = fopen(file, "r")) == NULL) {
-               if (!complain) 
+               if (!complain)
                        return -1;
                radlog(L_CONS|L_ERR, "Couldn't open %s for reading: %s",
                                file, strerror(errno));
@@ -160,6 +98,20 @@ int pairlist_read(const char *file, PAIR_LIST **list, int complain)
                        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) {
                        /*
@@ -168,8 +120,8 @@ parse_again:
                        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;
                                }
@@ -200,7 +152,7 @@ parse_again:
                                 *      file.
                                 */
                                if (*s != '/') {
-                                       strNcpy(newfile, file,
+                                       strlcpy(newfile, file,
                                                sizeof(newfile));
                                        ptr = strrchr(newfile, '/');
                                        strcpy(ptr + 1, s);
@@ -211,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;
                        }
 
@@ -233,7 +188,7 @@ parse_again:
                        reply_tmp = NULL;
                        old_lineno = lineno;
                        parsecode = userparse(ptr, &check_tmp);
-                       if (parsecode == T_INVALID) {
+                       if (parsecode == T_OP_INVALID) {
                                pairlist_free(&pl);
                                radlog(L_ERR|L_CONS,
                                "%s[%d]: Parse error (check) for entry %s: %s",
@@ -242,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;
                        }
@@ -254,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;
                                }
@@ -268,8 +223,8 @@ parse_again:
                                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;
                                }
@@ -280,7 +235,6 @@ parse_again:
                                 */
                                t = rad_malloc(sizeof(PAIR_LIST));
 
-                               auth_type_fixup(&check_tmp);
                                memset(t, 0, sizeof(*t));
                                t->name = strdup(entry);
                                t->check = check_tmp;
@@ -288,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)
@@ -340,313 +292,3 @@ static void debug_pair_list(PAIR_LIST *pl)
        }
 }
 #endif
-
-#ifndef BUILDDBM /* HACK HACK */
-
-/*
- *     Free a REALM list.
- */
-void realm_free(REALM *cl)
-{
-       REALM *next;
-
-       while(cl) {
-               next = cl->next;
-               free(cl);
-               cl = next;
-       }
-}
-
-/*
- *     Read the realms file.
- */
-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, **tail;
-
-       realm_free(mainconfig.realms);
-       mainconfig.realms = NULL;
-       tail = &mainconfig.realms;
-
-       if ((fp = fopen(file, "r")) == NULL) {
-               /* The realms file is not mandatory.  If it exists it will
-                  be used, however, since the new style config files are
-                  more robust and flexible they are more likely to get used.
-                  So this is a non-fatal error.  */
-               return 0;
-       }
-       while(fgets(buffer, 256, fp) != NULL) {
-               lineno++;
-               if (!feof(fp) && (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;
-               }
-
-               c = rad_malloc(sizeof(REALM));
-               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 = PW_AUTH_UDP_PORT;
-                       c->acct_port = PW_ACCT_UDP_PORT;
-               }
-
-               if (strcmp(hostnm, "LOCAL") == 0) {
-                       /*
-                        *      Local realms don't have an IP address,
-                        *      secret, or port.
-                        */
-                       c->acct_ipaddr = c->ipaddr = htonl(INADDR_NONE);
-                       c->secret[0] = '\0';
-                       c->auth_port = auth_port;
-                       c->acct_port = acct_port;
-
-               } else {
-                       RADCLIENT *client;
-                       c->ipaddr = ip_getaddr(hostnm);
-                       c->acct_ipaddr = c->ipaddr;
-
-                       if (c->ipaddr == htonl(INADDR_NONE)) {
-                               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;
-               c->active = TRUE;
-               c->acct_active = 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, "notrealm") != NULL)
-                               c->notrealm = 1;
-                       if (strstr(opts, "notsuffix") != NULL)
-                               c->notrealm = 1;
-               }
-
-               c->next = NULL;
-               *tail = c;
-               tail = &c->next;
-       }
-       fclose(fp);
-
-       return 0;
-}
-#endif /* BUILDDBM */
-
-/*
- * Mark a host inactive
- */
-void realm_disable(uint32_t ipaddr, int port)
-{
-       REALM *cl;
-       time_t now;
-
-       now = time(NULL);
-       for(cl = mainconfig.realms; cl; cl = cl->next) {
-               if ((ipaddr == cl->ipaddr) && (port == cl->auth_port)) {
-                       /*
-                        *      If we've received a reply (any reply)
-                        *      from the home server in the time spent
-                        *      re-sending this request, then don't mark
-                        *      the realm as dead.
-                        */
-                       if (cl->last_reply > (( now - mainconfig.proxy_retry_delay * mainconfig.proxy_retry_count ))) {
-                               continue;
-                       }
-
-                       cl->active = FALSE;
-                       cl->wakeup = now + mainconfig.proxy_dead_time;
-                       radlog(L_PROXY, "marking authentication server %s:%d for realm %s dead",
-                               cl->server, port, cl->realm);
-               } else if ((ipaddr == cl->acct_ipaddr) && (port == cl->acct_port)) {
-                       if (cl->last_reply > (( now - mainconfig.proxy_retry_delay * mainconfig.proxy_retry_count ))) {
-                               continue;
-                       }
-
-                       cl->acct_active = FALSE;
-                       cl->acct_wakeup = now + mainconfig.proxy_dead_time;
-                       radlog(L_PROXY, "marking accounting server %s:%d for realm %s dead",
-                               cl->server, port, cl->realm);
-               }
-       }
-}
-
-/*
- *     Find a realm in the REALM list.
- */
-REALM *realm_find(const char *realm, int accounting)
-{
-       REALM *cl;
-       REALM *default_realm = NULL;
-       time_t now;
-       int dead_match = 0;
-
-       now = time(NULL);
-
-       /*
-        *      If we're passed a NULL realm pointer,
-        *      then look for a "NULL" realm string.
-        */
-       if (realm == NULL) {
-               realm = "NULL";
-       }
-       
-       for (cl = mainconfig.realms; cl; cl = cl->next) {
-               /*
-                *      Wake up any sleeping realm.
-                */
-               if (cl->wakeup <= now) {
-                       cl->active = TRUE;
-               }
-               if (cl->acct_wakeup <= now) {
-                       cl->acct_active = TRUE;
-               }
-
-               /*
-                *      Asked for auth/acct, and the auth/acct server
-                *      is not active.  Skip it.
-                */
-               if ((!accounting && !cl->active) ||
-                   (accounting && !cl->acct_active)) {
-
-                       /*
-                        *      We've been asked to NOT fall through
-                        *      to the DEFAULT realm if there are
-                        *      exact matches for this realm which are
-                        *      dead.
-                        */
-                       if ((!mainconfig.proxy_fallback) &&
-                           (strcasecmp(cl->realm, realm) == 0)) {
-                               dead_match = 1;
-                       }
-                       continue;
-               }
-
-               /*
-                *      If it matches exactly, return it.
-                *
-                *      Note that we just want ONE live realm
-                *      here.  We don't care about round-robin, or
-                *      scatter techniques, as that's more properly
-                *      the responsibility of the proxying code.
-                */
-               if (strcasecmp(cl->realm, realm) == 0) {
-                       return cl;
-               }
-
-               /*
-                *      No default realm, try to set one.
-                */
-               if ((default_realm == NULL) &&
-                   (strcmp(cl->realm, "DEFAULT") == 0)) {
-                 default_realm = cl;
-               }
-       } /* loop over all realms */
-
-       /*
-        *      There WAS one or more matches which were marked dead,
-        *      AND there were NO live matches, AND we've been asked
-        *      to NOT fall through to the DEFAULT realm.  Therefore,
-        *      we return NULL, which means "no match found".
-        */
-       if (!mainconfig.proxy_fallback && dead_match) {
-               return NULL;
-       }
-
-       /*
-        *      Didn't find anything that matched exactly, return the
-        *      DEFAULT realm.  We also return the DEFAULT realm if
-        *      all matching realms were marked dead, and we were
-        *      asked to fall through to the DEFAULT realm in this
-        *      case.
-        */
-       return default_realm;
-}
-
-/*
- *     Find a realm for a proxy reply by proxy's IP
- *
- *     Note that we don't do anything else.
- */
-REALM *realm_findbyaddr(uint32_t ipaddr, int port)
-{
-       REALM *cl;
-       
-       /*
-        *      Note that we do NOT check for inactive realms!
-        *
-        *      The purpose of this code is simply to find a matching
-        *      source IP/Port pair, for a home server which is allowed
-        *      to send us proxy replies.  If we get a reply, then it
-        *      doesn't matter if we think the realm is inactive.
-        */
-       for (cl = mainconfig.realms; cl != NULL; cl = cl->next) {
-               if ((ipaddr == cl->ipaddr) && (port == cl->auth_port)) {
-                       return cl;
-
-               } else if ((ipaddr == cl->acct_ipaddr) && (port == cl->acct_port)) {
-                       return cl;
-               }
-       }
-
-       return NULL;
-}
-