Massively cleaned up #include's, so they're in a consistent
[freeradius.git] / src / main / valuepair.c
index e20f4d0..76e962c 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  Alan DeKok <aland@ox.org>
  */
 
-static const char rcsid[] = "$Id$";
+#include <freeradius-devel/ident.h>
+RCSID("$Id$")
 
-#include "autoconf.h"
-#include "libradius.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_NETINET_IN_H
-#      include <netinet/in.h>
-#endif
+#include <freeradius-devel/radiusd.h>
 
 #ifdef HAVE_REGEX_H
 #      include <regex.h>
@@ -52,8 +44,6 @@ static const char rcsid[] = "$Id$";
 #endif
 #endif
 
-#include "radiusd.h"
-
 struct cmp {
        int attribute;
        int otherattr;
@@ -67,21 +57,13 @@ static struct cmp *cmp;
 /*
  *     Compare 2 attributes. May call the attribute compare function.
  */
-static int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check,
+static int compare_pair(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check,
                       VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
 {
        int ret = -2;
        struct cmp *c;
 
        /*
-        *      Sanity check.
-        */
-#if 0
-       if (request->attribute != check->attribute)
-               return -2;
-#endif
-
-       /*
         *      Check for =* and !* and return appropriately
         */
        if( check->operator == T_OP_CMP_TRUE )
@@ -91,12 +73,16 @@ static int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check,
 
        /*
         *      See if there is a special compare function.
+        *
+        *      FIXME: use new RB-Tree code.
         */
        for (c = cmp; c; c = c->next)
                if (c->attribute == check->attribute)
                        return (c->compare)(c->instance, req, request, check,
                                check_pairs, reply_pairs);
 
+       if (!request) return -1; /* doesn't exist, don't compare it */
+
        switch(check->type) {
 #ifdef ASCEND_BINARY
                /*
@@ -110,16 +96,16 @@ static int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check,
                                ret = 1; /* NOT equal */
                                break;
                        }
-                       ret = memcmp(request->strvalue, check->strvalue,
+                       ret = memcmp(request->vp_strvalue, check->vp_strvalue,
                                        request->length);
                        break;
                case PW_TYPE_STRING:
                        if (check->flags.caseless) {
-                               ret = strcasecmp((char *)request->strvalue,
-                                                (char *)check->strvalue);
+                               ret = strcasecmp((char *)request->vp_strvalue,
+                                                (char *)check->vp_strvalue);
                        } else {
-                               ret = strcmp((char *)request->strvalue,
-                                            (char *)check->strvalue);
+                               ret = strcmp((char *)request->vp_strvalue,
+                                            (char *)check->vp_strvalue);
                        }
                        break;
                case PW_TYPE_INTEGER:
@@ -127,8 +113,23 @@ static int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check,
                        ret = request->lvalue - check->lvalue;
                        break;
                case PW_TYPE_IPADDR:
-                       ret = ntohl(request->lvalue) - ntohl(check->lvalue);
+                       ret = ntohl(request->vp_ipaddr) - ntohl(check->vp_ipaddr);
                        break;
+               case PW_TYPE_IPV6ADDR:
+                       ret = memcmp(&request->vp_ipv6addr, &check->vp_ipv6addr,
+                                    sizeof(request->vp_ipv6addr));
+                       break;
+                       
+               case PW_TYPE_IPV6PREFIX:
+                       ret = memcmp(&request->vp_ipv6prefix, &check->vp_ipv6prefix,
+                                    sizeof(request->vp_ipv6prefix));
+                       break;
+               
+               case PW_TYPE_IFID:
+                       ret = memcmp(&request->vp_ifid, &check->vp_ifid,
+                                    sizeof(request->vp_ifid));
+                       break;
+
                default:
                        break;
        }
@@ -216,7 +217,7 @@ void paircompare_unregister(int attr, RAD_COMPARE_FUNC fun)
  *
  *     Return 0 on match.
  */
-int paircmp(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR **reply)
+int paircompare(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR **reply)
 {
        VALUE_PAIR *check_item;
        VALUE_PAIR *auth_item;
@@ -261,8 +262,8 @@ int paircmp(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR **r
                         *
                         *      This hack makes CHAP-Password work..
                         */
-                       case PW_PASSWORD:
-                               if (pairfind(request, PW_PASSWORD) == NULL) {
+                       case PW_USER_PASSWORD:
+                               if (pairfind(request, PW_USER_PASSWORD) == NULL) {
                                        continue;
                                }
                                break;
@@ -308,11 +309,11 @@ int paircmp(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR **r
                 */
                if (check_item->flags.do_xlat) {
                        int rcode;
-                       char buffer[sizeof(check_item->strvalue)];
+                       char buffer[sizeof(check_item->vp_strvalue)];
 
                        check_item->flags.do_xlat = 0;
                        rcode = radius_xlat(buffer, sizeof(buffer),
-                                           check_item->strvalue,
+                                           check_item->vp_strvalue,
                                            req, NULL);
 
                        /*
@@ -324,7 +325,7 @@ int paircmp(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR **r
                /*
                 *      OK it is present now compare them.
                 */
-               compare = paircompare(req, auth_item, check_item, check, reply);
+               compare = compare_pair(req, auth_item, check_item, check, reply);
 
                switch (check_item->operator) {
                        case T_OP_EQ:
@@ -362,24 +363,32 @@ int paircmp(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR **r
                        case T_OP_REG_EQ:
                        {
                                int i;
-                               regmatch_t rxmatch[9];
+                               regmatch_t rxmatch[REQUEST_MAX_REGEX + 1];
+
+                               if ((auth_item->type == PW_TYPE_IPADDR) &&
+                                   (auth_item->vp_strvalue[0] == '\0')) {
+                                 inet_ntop(AF_INET, &(auth_item->lvalue),
+                                           auth_item->vp_strvalue,
+                                           sizeof(auth_item->vp_strvalue));
+                               }
 
                                /*
                                 *      Include substring matches.
                                 */
-                               regcomp(&reg, (char *)check_item->strvalue,
+                               regcomp(&reg, (char *)check_item->vp_strvalue,
                                        REG_EXTENDED);
                                compare = regexec(&reg,
-                                                 (char *)auth_item->strvalue,
-                                                 16, rxmatch, 0);
+                                                 (char *)auth_item->vp_strvalue,
+                                                 REQUEST_MAX_REGEX + 1,
+                                                 rxmatch, 0);
                                regfree(&reg);
 
                                /*
                                 *      Add %{0}, %{1}, etc.
                                 */
-                               for (i = 0; i <= 8; i++) {
+                               for (i = 0; i <= REQUEST_MAX_REGEX; i++) {
                                        char *p;
-                                       char buffer[sizeof(check_item->strvalue)];
+                                       char buffer[sizeof(check_item->vp_strvalue)];
 
                                        /*
                                         *      Didn't match: delete old
@@ -405,7 +414,7 @@ int paircmp(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR **r
                                         *      Copy substring into buffer.
                                         */
                                        memcpy(buffer,
-                                              auth_item->strvalue + rxmatch[i].rm_so,
+                                              auth_item->vp_strvalue + rxmatch[i].rm_so,
                                               rxmatch[i].rm_eo - rxmatch[i].rm_so);
                                        buffer[rxmatch[i].rm_eo - rxmatch[i].rm_so] = '\0';
 
@@ -428,8 +437,15 @@ int paircmp(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR **r
                                break;
 
                        case T_OP_REG_NE:
-                               regcomp(&reg, (char *)check_item->strvalue, REG_EXTENDED|REG_NOSUB);
-                               compare = regexec(&reg, (char *)auth_item->strvalue,
+                               if ((auth_item->type == PW_TYPE_IPADDR) &&
+                                   (auth_item->vp_strvalue[0] == '\0')) {
+                                 inet_ntop(AF_INET, &(auth_item->lvalue),
+                                           auth_item->vp_strvalue,
+                                           sizeof(auth_item->vp_strvalue));
+                               }
+
+                               regcomp(&reg, (char *)check_item->vp_strvalue, REG_EXTENDED|REG_NOSUB);
+                               compare = regexec(&reg, (char *)auth_item->vp_strvalue,
                                                0, NULL, 0);
                                regfree(&reg);
                                if (compare == 0) result = -1;
@@ -454,12 +470,12 @@ int paircmp(REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR **r
 }
 
 /*
- *      Compare two attributes simply.  Calls paircompare.
+ *      Compare two attributes simply.  Calls compare_pair.
  */
 
 int simplepaircmp(REQUEST *req, VALUE_PAIR *first, VALUE_PAIR *second)
 {
-       return paircompare( req, first, second, NULL, NULL );
+       return compare_pair( req, first, second, NULL, NULL );
 }
 
 
@@ -503,11 +519,11 @@ void pairxlatmove(REQUEST *req, VALUE_PAIR **to, VALUE_PAIR **from)
                 */
                if (i->flags.do_xlat) {
                        int rcode;
-                       char buffer[sizeof(i->strvalue)];
+                       char buffer[sizeof(i->vp_strvalue)];
 
                        i->flags.do_xlat = 0;
                        rcode = radius_xlat(buffer, sizeof(buffer),
-                                           i->strvalue,
+                                           i->vp_strvalue,
                                            req, NULL);
 
                        /*
@@ -525,9 +541,9 @@ void pairxlatmove(REQUEST *req, VALUE_PAIR **to, VALUE_PAIR **from)
                         */
                case T_OP_SUB:          /* -= */
                        if (found) {
-                               if (!i->strvalue[0] ||
-                                   (strcmp((char *)found->strvalue,
-                                           (char *)i->strvalue) == 0)){
+                               if (!i->vp_strvalue[0] ||
+                                   (strcmp((char *)found->vp_strvalue,
+                                           (char *)i->vp_strvalue) == 0)){
                                        pairdelete(to, found->attribute);
 
                                        /*