Massively cleaned up #include's, so they're in a consistent
[freeradius.git] / src / modules / rlm_fastusers / rlm_fastusers.c
index 5420546..b63251c 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  Jeff Carneal <jeff@apex.net>
  */
 
-#include        "autoconf.h"
-#include        "libradius.h"
+#include        <freeradius-devel/ident.h>
+RCSID("$Id$")
+
+#include       <freeradius-devel/radiusd.h>
+#include       <freeradius-devel/modules.h>
 
-#include       <sys/socket.h>
-#include       <sys/time.h>
 #include       <sys/stat.h>
 
-#include       <stdio.h>
-#include       <stdlib.h>
-#include       <string.h>
 #include       <pwd.h>
 #include       <grp.h>
 #include       <ctype.h>
 #include       <fcntl.h>
 #include       <limits.h>
 
-#include       "radiusd.h"
-#include       "modules.h"
-
 struct fastuser_instance {
        char *compat_mode;
        int hash_reload;
 
        /* hash table */
-       long hashsize;
+       int hashsize;
        PAIR_LIST **hashtable;
        PAIR_LIST *defaults;
        PAIR_LIST *acctusers;
@@ -62,20 +57,19 @@ struct fastuser_instance {
 /* Function declarations */
 static int fallthrough(VALUE_PAIR *vp);
 static int fastuser_buildhash(struct fastuser_instance *inst);
-static int fastuser_getfile(struct fastuser_instance *inst, const char *filename, 
-                                                                                                               PAIR_LIST **default_list, PAIR_LIST **pair_list, 
+static int fastuser_getfile(struct fastuser_instance *inst, const char *filename,
+                                                                                                               PAIR_LIST **default_list, PAIR_LIST **pair_list,
                                                                                                                int isacctfile);
-static int fastuser_hash(const char *s, long hashtablesize);
+static int fastuser_hash(const char *s, int hashtablesize);
 static int fastuser_store(PAIR_LIST **hashtable, PAIR_LIST *entry, int idx);
 static PAIR_LIST *fastuser_find(REQUEST *request, PAIR_LIST *user,
                                                                                                                                const char *username);
-static void fastuser_tablestats(PAIR_LIST **hashtable, long size);
-static int fastuser_passcheck(REQUEST *request, PAIR_LIST *user, const char *name);
+static void fastuser_tablestats(PAIR_LIST **hashtable, int size);
 
-static CONF_PARSER module_config[] = {
-       { "usersfile",     PW_TYPE_STRING_PTR,
+static const CONF_PARSER module_config[] = {
+       { "usersfile",     PW_TYPE_FILENAME,
          offsetof(struct fastuser_instance,usersfile), NULL, "${raddbdir}/users_fast" },
-       { "acctusersfile",     PW_TYPE_STRING_PTR,
+       { "acctusersfile",     PW_TYPE_FILENAME,
          offsetof(struct fastuser_instance,acctusersfile), NULL, "${raddbdir}/acct_users" },
        { "hashsize",     PW_TYPE_INTEGER,
          offsetof(struct fastuser_instance,hashsize), NULL, "100000" },
@@ -106,7 +100,7 @@ static int rad_check_return(VALUE_PAIR *list)
 {
       VALUE_PAIR      *authtype;
 
-      /* 
+      /*
        * We check for Auth-Type = Reject here
        */
 
@@ -120,7 +114,7 @@ static int rad_check_return(VALUE_PAIR *list)
 }
 
 static int fastuser_buildhash(struct fastuser_instance *inst) {
-       long memsize=0;
+       int memsize=0;
        int rcode, hashindex;
        PAIR_LIST **newhash=NULL, **oldhash=NULL;
        PAIR_LIST *newdefaults=NULL, *newacctusers, *cur=NULL;
@@ -129,7 +123,7 @@ static int fastuser_buildhash(struct fastuser_instance *inst) {
        int reloadusers = 1;
        int reloadacctusers = 1;
 
-       /* 
+       /*
         * Allocate space for hash table here
         */
        memsize = sizeof(PAIR_LIST *) * inst->hashsize;
@@ -196,7 +190,7 @@ static int fastuser_buildhash(struct fastuser_instance *inst) {
                                        cur = oldhash[hashindex];
                                        pairlist_free(&cur);
                                }
-                       } 
+                       }
                        free(oldhash);
                }
                pairlist_free(&olddefaults);
@@ -208,14 +202,14 @@ static int fastuser_buildhash(struct fastuser_instance *inst) {
                pairlist_free(&oldacctusers);
        }
 
-       if(inst->stats) 
+       if(inst->stats)
                fastuser_tablestats(inst->hashtable, inst->hashsize);
 
-       return 0;       
+       return 0;
 }
 
-static int fastuser_getfile(struct fastuser_instance *inst, const char *filename, 
-                                                                                                               PAIR_LIST **default_list, PAIR_LIST **pair_list, 
+static int fastuser_getfile(struct fastuser_instance *inst, const char *filename,
+                                                                                                               PAIR_LIST **default_list, PAIR_LIST **pair_list,
                                                                                                                int isacctfile) {
        int rcode;
        PAIR_LIST *users = NULL;
@@ -223,7 +217,7 @@ static int fastuser_getfile(struct fastuser_instance *inst, const char *filename
        int compat_mode = FALSE;
        VALUE_PAIR *vp=NULL;
        int hashindex = 0;
-       long numdefaults = 0, numusers=0;
+       int numdefaults = 0, numusers=0;
 
        radlog(L_INFO, " fastusers:  Reading %s", filename);
        rcode = pairlist_read(filename, &users, 1);
@@ -234,7 +228,7 @@ static int fastuser_getfile(struct fastuser_instance *inst, const char *filename
        if (strcmp(inst->compat_mode, "cistron") == 0) {
                compat_mode = TRUE;
        }
-        
+
        entry = users;
        while (entry) {
                if (compat_mode) {
@@ -254,13 +248,13 @@ static int fastuser_getfile(struct fastuser_instance *inst, const char *filename
                         *      Ignore attributes which are set
                         *      properly.
                         */
-                       if (vp->operator != T_OP_EQ) 
+                       if (vp->operator != T_OP_EQ)
                                continue;
-                               
+
 
                        /*
                         *      If it's a vendor attribute,
-                        *      or it's a wire protocol, 
+                        *      or it's a wire protocol,
                         *      ensure it has '=='.
                         */
                        if (((vp->attribute & ~0xffff) != 0) ||
@@ -275,7 +269,7 @@ static int fastuser_getfile(struct fastuser_instance *inst, const char *filename
                                vp->operator = T_OP_CMP_EQ;
                                continue;
                        }
-                               
+
                        /*
                         *      Cistron Compatibility mode.
                         *
@@ -304,10 +298,10 @@ static int fastuser_getfile(struct fastuser_instance *inst, const char *filename
                                        vp->operator = T_OP_CMP_EQ;
                                }
                        }
-                               
+
                } /* end of loop over check items */
-                
-                
+
+
                /*
                 *      Look for server configuration items
                 *      in the reply list.
@@ -329,7 +323,7 @@ static int fastuser_getfile(struct fastuser_instance *inst, const char *filename
                                log_debug("[%s]:%d WARNING! Check item \"%s\"\n"
                                        "\tfound in reply item list for user \"%s\".\n"
                                        "\tThis attribute MUST go on the first line"
-                                       " with the other check items", 
+                                       " with the other check items",
                                        filename, entry->lineno, vp->name,
                                        entry->name);
                        }
@@ -348,11 +342,11 @@ static int fastuser_getfile(struct fastuser_instance *inst, const char *filename
                if(!isacctfile) {
                        /* Save the DEFAULT entry specially */
                        if(strcmp(entry->name, "DEFAULT")==0) {
-                               
+
                                /* Save this as the last default we've seen */
                                lastdefault = entry;
                                numdefaults++;
-       
+
                                /* put it at the end of the list */
                                if(defaults) {
                                        for(cur=defaults; cur->next; cur=cur->next);
@@ -360,18 +354,18 @@ static int fastuser_getfile(struct fastuser_instance *inst, const char *filename
                                        entry->next = NULL;
                                } else {
                                        defaults = entry;
-                                       defaults->next = NULL; 
+                                       defaults->next = NULL;
                                }
-       
+
                        } else {
                                numusers++;
-       
+
                                /* Hash the username */
                                hashindex = fastuser_hash(entry->name, inst->hashsize);
-       
+
                                /* Store the last default before this entry */
                                entry->lastdefault = lastdefault;
-       
+
                                /* Store user in the hash */
                                fastuser_store(pair_list, entry, hashindex);
                        }
@@ -383,7 +377,7 @@ static int fastuser_getfile(struct fastuser_instance *inst, const char *filename
 
        if(!isacctfile && (default_list)) {
                *default_list = defaults;
-               radlog(L_INFO, "rlm_fastusers:  Loaded %ld users and %ld defaults",
+               radlog(L_INFO, "rlm_fastusers:  Loaded %d users and %d defaults",
                                        numusers, numdefaults);
        } else {
                *pair_list = users;
@@ -393,8 +387,8 @@ static int fastuser_getfile(struct fastuser_instance *inst, const char *filename
 }
 
 /* Hashes the username sent to it and returns index into hashtable */
-int fastuser_hash(const char *s, long hashtablesize) {
-       unsigned long hash = 0;
+int fastuser_hash(const char *s, int hashtablesize) {
+       unsigned int hash = 0;
 
        while (*s != '\0') {
                hash = hash * 7907 + (unsigned char)*s++;
@@ -410,7 +404,7 @@ static int fastuser_store(PAIR_LIST **hashtable, PAIR_LIST *new, int idx) {
        cur = hashtable[idx];
        /* store new record at end of list */
        if(cur) {
-               while (cur->next != NULL) 
+               while (cur->next != NULL)
                        cur=cur->next;
                cur->next = new;
                new->next = NULL;
@@ -425,7 +419,7 @@ static int fastuser_store(PAIR_LIST **hashtable, PAIR_LIST *new, int idx) {
  * Looks up user in hashtable.  If user can't be found, returns 0.
  * Otherwise returns a pointer to the structure for the user
  */
-static PAIR_LIST *fastuser_find(REQUEST *request, PAIR_LIST *user, 
+static PAIR_LIST *fastuser_find(REQUEST *request, PAIR_LIST *user,
                                            const char *username)
 {
        PAIR_LIST *cur=user;
@@ -437,20 +431,9 @@ static PAIR_LIST *fastuser_find(REQUEST *request, PAIR_LIST *user,
         */
        while((cur) && (!userfound)) {
                if((strcmp(cur->name, username)==0) &&
-                               paircmp(request, request->packet->vps, cur->check, &request->reply->vps) == 0) {
-                       /*
-                        * Usercollide means we have to compare check pairs
-                        * AND the password
-                        */
-                       if(mainconfig.do_usercollide) {
-                               if((userfound = fastuser_passcheck(request, cur, username))==0) {
-                                       cur = cur->next;
-                               } 
-
-                       } else {
+                               paircompare(request, request->packet->vps, cur->check, &request->reply->vps) == 0) {
                                userfound = 1;
                                DEBUG2("  fastusers: Matched %s at %d", cur->name, cur->lineno);
-                       }
                } else {
                        cur = cur->next;
                }
@@ -466,7 +449,7 @@ static PAIR_LIST *fastuser_find(REQUEST *request, PAIR_LIST *user,
 /*
  * Generate and log statistics about our hash table
  */
-static void fastuser_tablestats(PAIR_LIST **hashtable, long size) {
+static void fastuser_tablestats(PAIR_LIST **hashtable, int size) {
        int i, count;
        int countarray[256];
        int toomany=0;
@@ -486,56 +469,18 @@ static void fastuser_tablestats(PAIR_LIST **hashtable, long size) {
                }
        }
 
-       for(i=0; i<256; i++) 
+       for(i=0; i<256; i++)
                if(countarray[i]) {
                        radlog(L_INFO, "rlm_fastusers:  Hash buckets with %d users:  %d",
                                                i, countarray[i]);
                }
 
        if(toomany) {
-               radlog(L_INFO, "rlm_fastusers:  Hash buckets with more than 256:  %d", 
+               radlog(L_INFO, "rlm_fastusers:  Hash buckets with more than 256:  %d",
                                        toomany);
        }
 }
 
-static int fastuser_passcheck(REQUEST *request, PAIR_LIST *user, const char *name)
-{
-       int found=0;
-       VALUE_PAIR      *check_save;
-
-       /* 
-        * We check for REJECT specially here or a REJECT
-        * user will never match
-        */
-       check_save = pairfind(user->check, PW_AUTHTYPE);
-       if((check_save) && check_save->lvalue == PW_AUTHTYPE_REJECT)  {
-               DEBUG2("  fastusers(uc):  User '%s' line %d is Auth-Type Reject, but usercollide match", 
-                                       user->name, user->lineno);
-               return 1;
-       }
-
-       /* Save the orginal config items */
-       check_save = request->config_items;
-       request->config_items = NULL;
-       
-       DEBUG2("  fastusers(uc): Checking %s at %d", user->name, user->lineno);
-
-       /* Copy this users check pairs to the request */
-       request->config_items = paircopy(user->check);
-
-       /* Check the req to see if we matched */
-       if(rad_check_password(request)==0) {
-               DEBUG2("  fastusers(uc): Matched %s at %d", user->name, user->lineno);
-               found = 1;
-       }
-
-       /* Restore check items */
-       pairfree(&request->config_items); 
-       request->config_items = check_save;
-
-       return found;
-}
-
 /*
  *     (Re-)read the "users" file into memory.
  */
@@ -544,7 +489,8 @@ static int fastuser_instantiate(CONF_SECTION *conf, void **instance)
        struct fastuser_instance *inst=0;
 
        inst = rad_malloc(sizeof *inst);
-
+       if (!inst)
+               return -1;
        memset(inst, 0, sizeof(*inst));
 
        if (cf_section_parse(conf, inst, module_config) < 0) {
@@ -598,7 +544,7 @@ static int fastuser_authorize(void *instance, REQUEST *request)
                radlog(L_INFO, "rlm_fastusers:  Reloading fastusers hash");
                if(fastuser_buildhash(inst) < 0) {
                        radlog(L_ERR, "rlm_fastusers:  error building user hash.  aborting");
-                       exit(1);
+                       return RLM_MODULE_FAIL;
                }
        }
 
@@ -606,7 +552,7 @@ static int fastuser_authorize(void *instance, REQUEST *request)
         *      Grab the canonical user name.
         */
        namepair = request->username;
-       name = namepair ? (char *) namepair->strvalue : "NONE";
+       name = namepair ? (char *) namepair->vp_strvalue : "NONE";
 
        /*
         *      Find the entry for the user.
@@ -614,10 +560,10 @@ static int fastuser_authorize(void *instance, REQUEST *request)
        hashidx = fastuser_hash(name, inst->hashsize);
        user = inst->hashtable[hashidx];
        if((user=fastuser_find(request, user, name))!=NULL) {
-               userfound = 1;          
+               userfound = 1;
        }
 
-       /* 
+       /*
         * If there's no lastdefault and we
         * don't fallthrough, just copy the
         * pairs for this user and return
@@ -627,7 +573,7 @@ static int fastuser_authorize(void *instance, REQUEST *request)
 
                check_tmp = paircopy(user->check);
                pairmove(&request->config_items, &check_tmp);
-               pairfree(&check_tmp); 
+               pairfree(&check_tmp);
 
                reply_tmp = paircopy(user->reply);
                pairmove(&request->reply->vps, &reply_tmp);
@@ -642,8 +588,8 @@ static int fastuser_authorize(void *instance, REQUEST *request)
                }
        }
 
-       /* 
-        * When we get here, we've either found 
+       /*
+        * When we get here, we've either found
         * the user or not, but to preserve order
         * we start at the top of the default
         * list and work our way thru
@@ -652,27 +598,27 @@ static int fastuser_authorize(void *instance, REQUEST *request)
         * and return
         */
        DEBUG2("rlm_fastusers:  checking defaults");
-                       
+
        curdefault = inst->defaults;
        while(curdefault) {
-               if(paircmp(request, request->packet->vps, curdefault->check, 
+               if(paircompare(request, request->packet->vps, curdefault->check,
                                                        &request->reply->vps) == 0) {
-                       DEBUG2("  fastusers: Matched %s at %d", 
+                       DEBUG2("  fastusers: Matched %s at %d",
                                                        curdefault->name, curdefault->lineno);
                        defaultfound = 1;
 
                        check_tmp = paircopy(curdefault->check);
                        pairmove(&request->config_items, &check_tmp);
-                       pairfree(&check_tmp); 
+                       pairfree(&check_tmp);
 
                        reply_tmp = paircopy(curdefault->reply);
                        pairmove(&request->reply->vps, &reply_tmp);
                        pairfree(&reply_tmp);
 
-                       /*                         
-                        * There's no fallthru on this default which    
-                        * is *before* we find the user in the file,         
-                        * so we know it's safe to quit here                        
+                       /*
+                        * There's no fallthru on this default which
+                        * is *before* we find the user in the file,
+                        * so we know it's safe to quit here
                         */
                        if (!fallthrough(curdefault->reply))
                          break;
@@ -691,7 +637,7 @@ static int fastuser_authorize(void *instance, REQUEST *request)
 
                        check_tmp = paircopy(user->check);
                        pairmove(&request->config_items, &check_tmp);
-                       pairfree(&check_tmp); 
+                       pairfree(&check_tmp);
 
                        reply_tmp = paircopy(user->reply);
                        pairmove(&request->reply->vps, &reply_tmp);
@@ -702,13 +648,13 @@ static int fastuser_authorize(void *instance, REQUEST *request)
                                return(rad_check_return(user->check));
                        }
 
-                       /* 
+                       /*
                         * Find next occurence of THIS user in
                         * the users file
                         */
                        user=user->next;
                        user=fastuser_find(request, user, name);
-               } 
+               }
 
                curdefault = curdefault->next;
        }
@@ -753,10 +699,10 @@ static int fastuser_preacct(void *instance, REQUEST *request)
        struct fastuser_instance *inst = instance;
 
        namepair = request->username;
-       name = namepair ? (char *) namepair->strvalue : "NONE";
+       name = namepair ? (char *) namepair->vp_strvalue : "NONE";
        request_pairs = request->packet->vps;
        config_pairs = &request->config_items;
-       
+
        /*
         *      Find the entry for the user.
         */
@@ -765,7 +711,7 @@ static int fastuser_preacct(void *instance, REQUEST *request)
                if (strcmp(name, pl->name) && strcmp(pl->name, "DEFAULT"))
                        continue;
 
-               if (paircmp(request, request_pairs, pl->check, &reply_pairs) == 0) {
+               if (paircompare(request, request_pairs, pl->check, &reply_pairs) == 0) {
                        DEBUG2("  acct_users: Matched %s at %d",
                               pl->name, pl->lineno);
                        found = 1;
@@ -813,32 +759,32 @@ static int fastuser_detach(void *instance)
                        cur = inst->hashtable[hashindex];
                        pairlist_free(&cur);
                }
-       } 
+       }
 
-       free(inst->compat_mode);
        free(inst->hashtable);
        pairlist_free(&inst->defaults);
        pairlist_free(&inst->acctusers);
-       free(inst->usersfile);
-       free(inst->acctusersfile);
-       free(inst);
        return 0;
 }
 
 /*
  *     This function is unused
  */
-static int fastuser_accounting(void *instance, REQUEST *request)
+static int fastuser_accounting(void *instance UNUSED, REQUEST *request UNUSED)
 {
+       /*
+        * FIXME: should re rather return RLM_MODULE_NOOP here?
+        */
        return RLM_MODULE_FAIL;
 }
 
 /* globally exported name */
 module_t rlm_fastusers = {
+       RLM_MODULE_INIT,
        "fastusers",
        0,                              /* type: reserved */
-       NULL,                           /* initialization */
        fastuser_instantiate,           /* instantiation */
+       fastuser_detach,                /* detach */
        {
                fastuser_authenticate,  /* authentication */
                fastuser_authorize,     /* authorization */
@@ -849,7 +795,5 @@ module_t rlm_fastusers = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
-       fastuser_detach,                /* detach */
-       NULL                            /* destroy */
 };