Updated API for 2.2.
[freeradius.git] / src / modules / rlm_ippool / rlm_ippool.c
index 6c6da88..6d811ea 100644 (file)
@@ -15,9 +15,9 @@
  *
  *   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 2001  The FreeRADIUS server project
+ * Copyright 2001,2006  The FreeRADIUS server project
  * Copyright 2002  Kostas Kalevras <kkalev@noc.ntua.gr>
  *
  * March 2002, Kostas Kalevras <kkalev@noc.ntua.gr>
  * - Make the key an MD5 of a configurable xlated string. This closes Bug #42
  */
 
-#include "config.h"
-#include "autoconf.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
+#include <freeradius-devel/ident.h>
+RCSID("$Id$")
 
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/modules.h>
 
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
+#include "config.h"
+#include <ctype.h>
 
-#include "radiusd.h"
-#include "modules.h"
-#include "conffile.h"
 #include "../../include/md5.h"
 
 #include <gdbm.h>
-#include <time.h>
 
 #ifdef NEEDS_GDBM_SYNC
 #      define GDBM_SYNCOPT GDBM_SYNC
 
 #define MAX_NAS_NAME_SIZE 64
 
-static const char rcsid[] = "$Id$";
-
 /*
  *     Define a structure for our module configuration.
  *
@@ -191,10 +170,8 @@ static int ippool_instantiate(CONF_SECTION *conf, void **instance)
        ippool_key key;
        datum key_datum;
        datum data_datum;
-       int i;
-       unsigned j;
        const char *cli = "0";
-       char *pool_name = NULL;
+       const char *pool_name = NULL;
 
        /*
         *      Set up a storage area for instance data
@@ -262,6 +239,7 @@ static int ippool_instantiate(CONF_SECTION *conf, void **instance)
                         * active = 0
                         */
                int rcode;
+               uint32_t i, j;
                uint32_t or_result;
                char str[32];
                char init_str[17];
@@ -301,9 +279,9 @@ static int ippool_instantiate(CONF_SECTION *conf, void **instance)
                        if (rcode < 0) {
                                radlog(L_ERR, "rlm_ippool: Failed storing data to %s: %s",
                                                data->session_db, gdbm_strerror(gdbm_errno));
-                               free(data);
                                gdbm_close(data->gdbm);
                                gdbm_close(data->ip);
+                               free(data);
                                return -1;
                        }
                }
@@ -341,41 +319,41 @@ static int ippool_accounting(void *instance, REQUEST *request)
        int num = 0;
        VALUE_PAIR *vp;
        char str[32];
-       char key_str[17];
+       uint8_t key_str[17];
        char hex_str[35];
        char xlat_str[MAX_STRING_LEN];
-       MD5_CTX md5_context;
+       FR_MD5_CTX md5_context;
 
 
-       if ((vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) != NULL)
-               acctstatustype = vp->lvalue;
+       if ((vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE, 0)) != NULL)
+               acctstatustype = vp->vp_integer;
        else {
-               DEBUG("rlm_ippool: Could not find account status type in packet. Return NOOP.");
+               RDEBUG("Could not find account status type in packet. Return NOOP.");
                return RLM_MODULE_NOOP;
        }
        switch(acctstatustype){
                case PW_STATUS_STOP:
                        if (!radius_xlat(xlat_str,MAX_STRING_LEN,data->key, request, NULL)){
-                               DEBUG("rlm_ippool: xlat on the 'key' directive failed");
+                               RDEBUG("xlat on the 'key' directive failed");
                                return RLM_MODULE_NOOP;
                        }
-                       MD5Init(&md5_context);
-                       MD5Update(&md5_context, xlat_str, strlen(xlat_str));
-                       MD5Final(key_str, &md5_context);
-                       key_str[17] = '\0';
-                       lrad_bin2hex(key_str,hex_str,16);
+                       fr_MD5Init(&md5_context);
+                       fr_MD5Update(&md5_context, xlat_str, strlen(xlat_str));
+                       fr_MD5Final(key_str, &md5_context);
+                       key_str[16] = '\0';
+                       fr_bin2hex(key_str,hex_str,16);
                        hex_str[32] = '\0';
-                       DEBUG("rlm_ippool: MD5 on 'key' directive maps to: %s",hex_str);
+                       RDEBUG("MD5 on 'key' directive maps to: %s",hex_str);
                        memcpy(key.key,key_str,16);
                        break;
                default:
                        /* We don't care about any other accounting packet */
-                       DEBUG("rlm_ippool: This is not an Accounting-Stop. Return NOOP.");
+                       RDEBUG("This is not an Accounting-Stop. Return NOOP.");
 
                        return RLM_MODULE_NOOP;
        }
 
-       DEBUG("rlm_ippool: Searching for an entry for key: '%s'",xlat_str);
+       RDEBUG("Searching for an entry for key: '%s'",xlat_str);
        key_datum.dptr = (char *) &key;
        key_datum.dsize = sizeof(ippool_key);
 
@@ -388,7 +366,7 @@ static int ippool_accounting(void *instance, REQUEST *request)
                 */
                memcpy(&entry, data_datum.dptr, sizeof(ippool_info));
                free(data_datum.dptr);
-               DEBUG("rlm_ippool: Deallocated entry for ip: %s",ip_ntoa(str,entry.ipaddr));
+               RDEBUG("Deallocated entry for ip: %s",ip_ntoa(str,entry.ipaddr));
                entry.active = 0;
                entry.timestamp = 0;
                entry.timeout = 0;
@@ -421,7 +399,7 @@ static int ippool_accounting(void *instance, REQUEST *request)
                        free(data_datum.dptr);
                        if (num >0){
                                num--;
-                               DEBUG("rlm_ippool: num: %d",num);
+                               RDEBUG("num: %d",num);
                                data_datum.dptr = (char *) &num;
                                data_datum.dsize = sizeof(int);
                                rcode = gdbm_store(data->ip, key_datum, data_datum, GDBM_REPLACE);
@@ -445,7 +423,7 @@ static int ippool_accounting(void *instance, REQUEST *request)
        }
        else{
                pthread_mutex_unlock(&data->op_mutex);
-               DEBUG("rlm_ippool: Entry not found");
+               RDEBUG("Entry not found");
        }
 
        return RLM_MODULE_OK;
@@ -469,10 +447,10 @@ static int ippool_postauth(void *instance, REQUEST *request)
        VALUE_PAIR *vp;
        char *cli = NULL;
        char str[32];
-       char key_str[17];
+       uint8_t key_str[17];
        char hex_str[35];
        char xlat_str[MAX_STRING_LEN];
-       MD5_CTX md5_context;
+       FR_MD5_CTX md5_context;
 
 
        /* quiet the compiler */
@@ -482,11 +460,11 @@ static int ippool_postauth(void *instance, REQUEST *request)
        /* Check if Pool-Name attribute exists. If it exists check our name and
         * run only if they match
         */
-       if ((vp = pairfind(request->config_items, PW_POOL_NAME)) != NULL){
-               if (data->name == NULL || (strcmp(data->name,vp->strvalue) && strcmp(vp->strvalue,"DEFAULT")))
+       if ((vp = pairfind(request->config_items, PW_POOL_NAME, 0)) != NULL){
+               if (data->name == NULL || (strcmp(data->name,vp->vp_strvalue) && strcmp(vp->vp_strvalue,"DEFAULT")))
                        return RLM_MODULE_NOOP;
        } else {
-               DEBUG("rlm_ippool: Could not find Pool-Name attribute.");
+               RDEBUG("Could not find Pool-Name attribute.");
                return RLM_MODULE_NOOP;
        }
 
@@ -494,24 +472,24 @@ static int ippool_postauth(void *instance, REQUEST *request)
        /*
         * Find the caller id
         */
-       if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) != NULL)
-               cli = vp->strvalue;
+       if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID, 0)) != NULL)
+               cli = vp->vp_strvalue;
 
 
        if (!radius_xlat(xlat_str,MAX_STRING_LEN,data->key, request, NULL)){
-               DEBUG("rlm_ippool: xlat on the 'key' directive failed");
+               RDEBUG("xlat on the 'key' directive failed");
                return RLM_MODULE_NOOP;
        }
-       MD5Init(&md5_context);
-       MD5Update(&md5_context, xlat_str, strlen(xlat_str));
-       MD5Final(key_str, &md5_context);
-       key_str[17] = '\0';
-       lrad_bin2hex(key_str,hex_str,16);
+       fr_MD5Init(&md5_context);
+       fr_MD5Update(&md5_context, xlat_str, strlen(xlat_str));
+       fr_MD5Final(key_str, &md5_context);
+       key_str[16] = '\0';
+       fr_bin2hex(key_str,hex_str,16);
        hex_str[32] = '\0';
-       DEBUG("rlm_ippool: MD5 on 'key' directive maps to: %s",hex_str);
+       RDEBUG("MD5 on 'key' directive maps to: %s",hex_str);
        memcpy(key.key,key_str,16);
 
-       DEBUG("rlm_ippool: Searching for an entry for key: '%s'",hex_str);
+       RDEBUG("Searching for an entry for key: '%s'",hex_str);
        key_datum.dptr = (char *) &key;
        key_datum.dsize = sizeof(ippool_key);
 
@@ -526,7 +504,7 @@ static int ippool_postauth(void *instance, REQUEST *request)
                memcpy(&entry, data_datum.dptr, sizeof(ippool_info));
                free(data_datum.dptr);
                if (entry.active){
-                       DEBUG("rlm_ippool: Found a stale entry for ip: %s",ip_ntoa(str,entry.ipaddr));
+                       RDEBUG("Found a stale entry for ip: %s",ip_ntoa(str,entry.ipaddr));
                        entry.active = 0;
                        entry.timestamp = 0;
                        entry.timeout = 0;
@@ -557,7 +535,7 @@ static int ippool_postauth(void *instance, REQUEST *request)
                                free(data_datum.dptr);
                                if (num >0){
                                        num--;
-                                       DEBUG("rlm_ippool: num: %d",num);
+                                       RDEBUG("num: %d",num);
                                        data_datum.dptr = (char *) &num;
                                        data_datum.dsize = sizeof(int);
                                        rcode = gdbm_store(data->ip, key_datum, data_datum, GDBM_REPLACE);
@@ -585,16 +563,16 @@ static int ippool_postauth(void *instance, REQUEST *request)
        /*
         * If there is a Framed-IP-Address attribute in the reply, check for override
         */
-       if (pairfind(request->reply->vps, PW_FRAMED_IP_ADDRESS) != NULL) {
-               DEBUG("rlm_ippool: Found Framed-IP-Address attribute in reply attribute list.");
+       if (pairfind(request->reply->vps, PW_FRAMED_IP_ADDRESS, 0) != NULL) {
+               RDEBUG("Found Framed-IP-Address attribute in reply attribute list.");
                if (data->override)
                {
                        /* Override supplied Framed-IP-Address */
-                       DEBUG("rlm_ippool: override is set to yes. Override the existing Framed-IP-Address attribute.");
-                       pairdelete(&request->reply->vps, PW_FRAMED_IP_ADDRESS);
+                       RDEBUG("override is set to yes. Override the existing Framed-IP-Address attribute.");
+                       pairdelete(&request->reply->vps, PW_FRAMED_IP_ADDRESS, 0);
                } else {
                        /* Abort */
-                       DEBUG("rlm_ippool: override is set to no. Return NOOP.");
+                       RDEBUG("override is set to no. Return NOOP.");
                        return RLM_MODULE_NOOP;
                }
        }
@@ -642,7 +620,7 @@ static int ippool_postauth(void *instance, REQUEST *request)
                                 * Find an entry with active == 0
                                 * or an entry that has expired
                                 */
-                               if (entry.active == 0 || (entry.timestamp && ((entry.timeout && 
+                               if (entry.active == 0 || (entry.timestamp && ((entry.timeout &&
                                request->timestamp >= (entry.timestamp + entry.timeout)) ||
                                (data->max_timeout && request->timestamp >= (entry.timestamp + data->max_timeout))))){
                                        datum tmp;
@@ -712,13 +690,13 @@ static int ippool_postauth(void *instance, REQUEST *request)
                        if (data_datum_tmp.dptr != NULL){
 
                                rcode = gdbm_store(data->gdbm, key_datum, data_datum_tmp, GDBM_REPLACE);
+                               free(data_datum_tmp.dptr);
                                if (rcode < 0) {
                                        radlog(L_ERR, "rlm_ippool: Failed storing data to %s: %s",
                                                data->session_db, gdbm_strerror(gdbm_errno));
                                                pthread_mutex_unlock(&data->op_mutex);
                                        return RLM_MODULE_FAIL;
                                }
-                               free(data_datum_tmp.dptr);
                        }
                }
                else{
@@ -751,8 +729,8 @@ static int ippool_postauth(void *instance, REQUEST *request)
                free(key_datum.dptr);
                entry.active = 1;
                entry.timestamp = request->timestamp;
-               if ((vp = pairfind(request->reply->vps, PW_SESSION_TIMEOUT)) != NULL)   
-                       entry.timeout = (time_t) vp->lvalue;
+               if ((vp = pairfind(request->reply->vps, PW_SESSION_TIMEOUT, 0)) != NULL)
+                       entry.timeout = (time_t) vp->vp_integer;
                else
                        entry.timeout = 0;
                if (extra)
@@ -782,7 +760,7 @@ static int ippool_postauth(void *instance, REQUEST *request)
                } else
                        num = 0;
                num++;
-               DEBUG("rlm_ippool: num: %d",num);
+               RDEBUG("num: %d",num);
                data_datum.dptr = (char *) &num;
                data_datum.dsize = sizeof(int);
                rcode = gdbm_store(data->ip, key_datum, data_datum, GDBM_REPLACE);
@@ -795,33 +773,26 @@ static int ippool_postauth(void *instance, REQUEST *request)
                pthread_mutex_unlock(&data->op_mutex);
 
 
-               DEBUG("rlm_ippool: Allocated ip %s to client key: %s",ip_ntoa(str,entry.ipaddr),hex_str);
-               if ((vp = paircreate(PW_FRAMED_IP_ADDRESS, PW_TYPE_IPADDR)) == NULL) {
-                       radlog(L_ERR|L_CONS, "no memory");
-                       return RLM_MODULE_FAIL;
-               }
-               vp->lvalue = entry.ipaddr;
-               ip_ntoa(vp->strvalue, vp->lvalue);
-               pairadd(&request->reply->vps, vp);
+               RDEBUG("Allocated ip %s to client key: %s",ip_ntoa(str,entry.ipaddr),hex_str);
+               vp = radius_paircreate(request, &request->reply->vps,
+                                      PW_FRAMED_IP_ADDRESS, 0, PW_TYPE_IPADDR);
+               vp->vp_ipaddr = entry.ipaddr;
 
                /*
                 *      If there is no Framed-Netmask attribute in the
                 *      reply, add one
                 */
-               if (pairfind(request->reply->vps, PW_FRAMED_IP_NETMASK) == NULL) {
-                       if ((vp = paircreate(PW_FRAMED_IP_NETMASK, PW_TYPE_IPADDR)) == NULL)
-                               radlog(L_ERR|L_CONS, "no memory");
-                       else {
-                               vp->lvalue = ntohl(data->netmask);
-                               ip_ntoa(vp->strvalue, vp->lvalue);
-                               pairadd(&request->reply->vps, vp);
-                       }
+               if (pairfind(request->reply->vps, PW_FRAMED_IP_NETMASK, 0) == NULL) {
+                       vp = radius_paircreate(request, &request->reply->vps,
+                                              PW_FRAMED_IP_NETMASK, 0,
+                                              PW_TYPE_IPADDR);
+                       vp->vp_ipaddr = ntohl(data->netmask);
                }
 
        }
        else{
                pthread_mutex_unlock(&data->op_mutex);
-               DEBUG("rlm_ippool: No available ip addresses in pool.");
+               RDEBUG("No available ip addresses in pool.");
                return RLM_MODULE_NOTFOUND;
        }
 
@@ -834,9 +805,6 @@ static int ippool_detach(void *instance)
 
        gdbm_close(data->gdbm);
        gdbm_close(data->ip);
-       free(data->session_db);
-       free(data->key);
-       free(data->ip_index);
        pthread_mutex_destroy(&data->op_mutex);
 
        free(instance);
@@ -853,10 +821,11 @@ static int ippool_detach(void *instance)
  *     is single-threaded.
  */
 module_t rlm_ippool = {
-       "IPPOOL",
+       RLM_MODULE_INIT,
+       "ippool",
        RLM_TYPE_THREAD_SAFE,           /* type */
-       NULL,                           /* initialization */
        ippool_instantiate,             /* instantiation */
+       ippool_detach,                  /* detach */
        {
                NULL,                   /* authentication */
                NULL,                   /* authorization */
@@ -867,6 +836,4 @@ module_t rlm_ippool = {
                NULL,                   /* post-proxy */
                ippool_postauth         /* post-auth */
        },
-       ippool_detach,                  /* detach */
-       NULL,                           /* destroy */
 };