Thanks Chris!

Your patch cleared things up. It's up and filtering now.
It was indeed very simple (well, you have to know what to look for ;-).

Chris

On Mon, 2003-08-11 at 14:57, Chris Brotsos wrote:
> 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 */



- 
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html

Reply via email to