At 11:03 AM 8/9/2003, you wrote:
Hi Chris,

I'm having problems finding your mail in the mailinglist history. It
could be too warm here to think about a good keyword to search for...
Can you post it again please?

Hello Chris,


It is attached as a file to this response. Please ignore the stuff about memset(). I had this version of attr_filter for awhile, and Alan advised me that the memset function was added to the instantiate function in a later release. So if you have the "memset(inst, 0, sizeof(*inst));" line in your instantiate function...that's a good thing :o)

Thanks,

Chris Brotsos
? cvsdiff.txt
Index: rlm_attr_filter.c
===================================================================
RCS file: /source/radiusd/src/modules/rlm_attr_filter/rlm_attr_filter.c,v
retrieving revision 1.13
diff -u -r1.13 rlm_attr_filter.c
--- rlm_attr_filter.c   7 Jul 2003 19:04:05 -0000       1.13
+++ rlm_attr_filter.c   11 Aug 2003 12:58:08 -0000
@@ -3,7 +3,7 @@
  *                      before sending reply to the NAS/Server that sent
  *                      it to us.
  *
- * Version:      $Id: rlm_attr_filter.c,v 1.13 2003/07/07 19:04:05 aland Exp $
+ * Version:      $Id: rlm_attr_filter.c,v 1.12 2002/08/24 16:54:56 aland Exp $
  *
  *   This program is is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License, version 2 if the
@@ -41,7 +41,7 @@
 #include       "radiusd.h"
 #include       "modules.h"
 
-static const char rcsid[] = "$Id: rlm_attr_filter.c,v 1.13 2003/07/07 19:04:05 aland 
Exp $";
+static const char rcsid[] = "$Id: rlm_attr_filter.c,v 1.12 2002/08/24 16:54:56 aland 
Exp $";
 
 struct attr_filter_instance {
 
@@ -152,10 +152,6 @@
        int rcode;
 
         inst = rad_malloc(sizeof *inst);
-       if (!inst) {
-               return -1;
-       }
-       memset(inst, 0, sizeof(*inst));
 
         if (cf_section_parse(conf, inst, module_config) < 0) {
                 free(inst);
@@ -407,6 +403,238 @@
 }
 
 /*
+ *     Find the named realm in the database.  Create the
+ *     set of attribute-value pairs to check and reply with
+ *     for this realm from the database.
+ */
+static int attr_filter_postproxy(void *instance, REQUEST *request)
+{
+       struct attr_filter_instance *inst = instance;
+       VALUE_PAIR      *request_pairs;
+       VALUE_PAIR      **reply_items;
+       VALUE_PAIR      *reply_item;
+       VALUE_PAIR      *reply_tmp = NULL;
+       VALUE_PAIR      *check_item;
+       PAIR_LIST       *pl;
+       int             found = 0;
+       int             compare;
+       int             pass, fail;
+#ifdef HAVE_REGEX_H
+       regex_t         reg;
+#endif
+       VALUE_PAIR      *realmpair;
+        REALM           *realm;
+        char            *realmname;
+
+       /*
+        *      It's not a proxy reply, so return NOOP
+        */
+
+       if( request->proxy == NULL ) {
+               return( RLM_MODULE_NOOP );
+       }
+
+       request_pairs = request->packet->vps;
+       reply_items = &request->proxy_reply->vps;
+
+       /*
+        *      Get the realm.  Can't use request->config_items as
+        *      that gets freed by rad_authenticate....  use the one
+        *      set in the original request vps
+        */
+       realmpair = pairfind(request_pairs, PW_REALM);
+       if(!realmpair) {
+               /*    Can't find a realm, so no filtering of attributes 
+                *    or should we use a DEFAULT entry?
+                *    For now, just return NOTFOUND. (maybe NOOP?)
+                */ 
+               return RLM_MODULE_NOTFOUND;
+       }
+
+       realmname = (char *) realmpair->strvalue;
+        realm = realm_find(realmname, FALSE);
+
+       /*
+        *      Find the attr_filter profile entry for the realm.
+        */
+       for(pl = inst->attrs; pl; pl = pl->next) {
+
+           /*
+            *  If the current entry is NOT a default,
+            *  AND the realm does NOT match the current entry,
+            *  then skip to the next entry.
+            */
+           if ( (strcmp(pl->name, "DEFAULT") != 0)
+                && (strcmp(realmname, pl->name) != 0) )  {
+                       continue;
+               }
+
+               DEBUG2("  attr_filter: Matched entry %s at line %d", pl->name, 
pl->lineno);
+
+               found = 1;
+               
+               check_item = pl->check;
+
+               while( check_item != NULL ) {
+
+                   /*
+                    *      If it is a SET operator, add the attribute to
+                    *      the reply list without checking reply_items.
+                    *
+                    */
+
+                   if( check_item->operator == T_OP_SET ) {
+                       mypairappend(check_item, &reply_tmp);
+                   }
+                   check_item = check_item->next;
+
+               }  /* while( check_item != NULL ) */
+
+               /* 
+                * Iterate through the reply items, comparing each reply item to every 
rule,
+                * then moving it to the reply_tmp list only if it matches all rules 
for that
+                * attribute.  IE, Idle-Timeout is moved only if it matches all rules 
that
+                * describe an Idle-Timeout.  
+                */
+
+               for( reply_item = *reply_items; 
+                    reply_item != NULL; 
+                    reply_item = reply_item->next ) {
+
+                 /* reset the pass,fail vars for each reply item */
+                 pass = fail = 0;
+
+                 /* reset the check_item pointer to the beginning of the list */
+                 check_item = pl->check;
+
+                 while( check_item != NULL ) {
+                     
+                     if(reply_item->attribute == check_item->attribute) {
+
+                       compare = simplepaircmp(request, reply_item, check_item);
+
+                       switch(check_item->operator) {
+
+                           case T_OP_SET:            /* nothing to do for set */
+                               break;
+                           case T_OP_EQ:
+                           default:
+                               radlog(L_ERR, "Invalid operator for item %s: "
+                                      "reverting to '=='", check_item->name);
+                               
+                           case T_OP_CMP_TRUE:       /* compare always == 0 */
+                           case T_OP_CMP_FALSE:      /* compare always == 1 */
+                           case T_OP_CMP_EQ:
+                               if (compare == 0) {
+                                   pass++;
+                               } else {
+                                   fail++;
+                               }
+                               break;
+
+                           case T_OP_NE:
+                               if (compare != 0) {
+                                   pass++;
+                               } else {
+                                   fail++;
+                               }
+                               break;
+
+                           case T_OP_LT:
+                               if (compare < 0) {
+                                   pass++;
+                               } else {
+                                   fail++;
+                               }
+                               break;
+
+                           case T_OP_GT:
+                               if (compare > 0) {
+                                   pass++;
+                               } else {
+                                   fail++;
+                               }
+                               break;
+                               
+                           case T_OP_LE:
+                               if (compare <= 0) {
+                                   pass++;
+                               } else {
+                                   fail++;
+                               }
+                               break;
+
+                           case T_OP_GE:
+                               if (compare >= 0) {
+                                   pass++;
+                               } else {
+                                   fail++;
+                               }
+                               break;
+#ifdef HAVE_REGEX_H
+                           case T_OP_REG_EQ:
+                               regcomp(&reg, (char *)check_item->strvalue, 0);
+                               compare = regexec(&reg, (char *)reply_item->strvalue,
+                                                 0, NULL, 0);
+                               regfree(&reg);
+                               if (compare == 0) {
+                                   pass++;
+                               } else {
+                                   fail++;
+                               }
+                               break;
+
+                           case T_OP_REG_NE:
+                               regcomp(&reg, (char *)check_item->strvalue, 0);
+                               compare = regexec(&reg, (char *)reply_item->strvalue,
+                                                 0, NULL, 0);
+                               regfree(&reg);
+                               if (compare != 0) {
+                                   pass++;
+                               } else {
+                                   fail++;
+                               }
+                               break;
+#endif
+                       }  /* switch( check_item->operator ) */
+
+                     }  /* if reply == check */
+
+                     check_item = check_item->next;
+
+                   }  /* while( check ) */
+
+                   /* only move attribute if it passed all rules */
+                   if (fail == 0 && pass > 0) {
+                     mypairappend( reply_item, &reply_tmp);
+                   }
+
+               }  /* for( reply ) */
+               
+               /* If we shouldn't fall through, break */
+               if(!fallthrough(pl->check))
+                   break;
+       }
+
+       pairfree(&request->proxy_reply->vps);
+       request->proxy_reply->vps = reply_tmp;
+       
+       /*
+        *      See if we succeeded.  If we didn't find the realm,
+        *      then exit from the module.
+        */
+       if (!found)
+               return RLM_MODULE_OK;
+
+       /*
+        *      Remove server internal parameters.
+        */
+       pairdelete(reply_items, PW_FALL_THROUGH);
+
+       return RLM_MODULE_UPDATED;
+}
+
+/*
  *     Clean up.
  */
 static int attr_filter_detach(void *instance)
@@ -432,7 +660,7 @@
                NULL,                   /* accounting */
                NULL,                   /* checksimul */
                NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
+               attr_filter_postproxy,  /* post-proxy */
                NULL                    /* post-auth */
        },
        attr_filter_detach,             /* detach */

Reply via email to