Removing attributes from a reply
Joe Maimon
jmaimon at ttec.com
Wed Oct 12 22:54:19 CEST 2005
in evaluate.c
if (rcode == FALSE && vp && (vp = vp->next))
instead of
if (rcode == FALSE && (vp = vp->next))
Joe Maimon wrote:
>
>
> Joe Maimon wrote:
>
>>
>>
>> Alan DeKok wrote:
>>
>>> Joe Maimon <jmaimon at ttec.com> wrote:
>>>
>>>> If I have the Framed-IP-Address attribute, I need to remove any
>>>> attribute of
>>>>
>>>> Cisco-AVPair -~ "ip:addr-pool.*"
>
>
> Ok got it to work with a bunch of hacks
>
> Included is
>
> -policy.txt file used(fresh from today)
> -substar&sunregex operator patch(old stuff works well)
> -policy patch (fresh from today)
>
>
>
>
> ------------------------------------------------------------------------
>
> #! /bin/sh /usr/share/dpatch/dpatch-run
> ## 030-substar_regex.patch.dpatch by <joe at nameserver3.ttec.com>
> ##
> ## All lines beginning with `## DP:' are a description of the patch.
> ## DP: No description.
>
> @DPATCH@
> diff -urNad freeradius-1.1.0pre0/man/man5/users.5 /tmp/dpep.fHbaO6/freeradius-1.1.0pre0/man/man5/users.5
> --- freeradius-1.1.0pre0/man/man5/users.5 2005-03-17 00:16:58.790666042 -0500
> +++ /tmp/dpep.fHbaO6/freeradius-1.1.0pre0/man/man5/users.5 2005-03-17 00:38:40.295848027 -0500
> @@ -95,6 +95,25 @@
> As a reply item, it has an identical meaning, but the attribute is
> added to the reply items.
>
> +
> +.TP 0.5i
> +.B "Attribute -= Value"
> +As a reply item it means remove matching items from the reply list.
> +.br
> +Not allowed as a check item.
> +
> +.TP 0.5i
> +.B "Attribute -* Value"
> +As a reply item it means remove all "Attribute" attributes items from the reply list.
> +.br
> +Not allowed as a check item.
> +
> +.TP 0.5i
> +.B "Attribute -~ Value"
> +As a reply item it means remove regex matching items from the reply list.
> +.br
> +Not allowed as a check item.
> +
> .TP 0.5i
> .B "Attribute != Value"
> As a check item, matches if the given attribute is in the request, AND
> diff -urNad freeradius-1.1.0pre0/src/include/token.h /tmp/dpep.fHbaO6/freeradius-1.1.0pre0/src/include/token.h
> --- freeradius-1.1.0pre0/src/include/token.h 2005-03-17 00:16:58.837659657 -0500
> +++ /tmp/dpep.fHbaO6/freeradius-1.1.0pre0/src/include/token.h 2005-03-17 00:38:40.296847890 -0500
> @@ -35,6 +35,8 @@
>
> T_OP_ADD, /* += */
> T_OP_SUB, /* -= */
> + T_OP_SUB_ALL, /* -* */
> + T_OP_SUB_REG, /* -~ */
> T_OP_SET, /* := */
> T_OP_EQ, /* = */
> T_OP_NE, /* != */
> diff -urNad freeradius-1.1.0pre0/src/lib/print.c /tmp/dpep.fHbaO6/freeradius-1.1.0pre0/src/lib/print.c
> --- freeradius-1.1.0pre0/src/lib/print.c 2005-03-17 00:16:58.842658978 -0500
> +++ /tmp/dpep.fHbaO6/freeradius-1.1.0pre0/src/lib/print.c 2005-03-17 00:38:40.297847754 -0500
> @@ -223,6 +223,8 @@
> ";",
> "+=",
> "-=",
> + "-*",
> + "-~",
> ":=",
> "=",
> "!=",
> diff -urNad freeradius-1.1.0pre0/src/lib/token.c /tmp/dpep.fHbaO6/freeradius-1.1.0pre0/src/lib/token.c
> --- freeradius-1.1.0pre0/src/lib/token.c 2005-03-17 00:16:58.843658842 -0500
> +++ /tmp/dpep.fHbaO6/freeradius-1.1.0pre0/src/lib/token.c 2005-03-17 00:38:40.299847482 -0500
> @@ -39,6 +39,8 @@
> { ",", T_COMMA, },
> { "+=", T_OP_ADD, },
> { "-=", T_OP_SUB, },
> + { "-*", T_OP_SUB_ALL, },
> + { "-~", T_OP_SUB_REG, },
> { ":=", T_OP_SET, },
> { "=*", T_OP_CMP_TRUE, },
> { "!*", T_OP_CMP_FALSE, },
> diff -urNad freeradius-1.1.0pre0/src/main/valuepair.c /tmp/dpep.fHbaO6/freeradius-1.1.0pre0/src/main/valuepair.c
> --- freeradius-1.1.0pre0/src/main/valuepair.c 2005-03-17 00:16:58.861656397 -0500
> +++ /tmp/dpep.fHbaO6/freeradius-1.1.0pre0/src/main/valuepair.c 2005-03-17 00:38:40.303846938 -0500
> @@ -467,7 +467,128 @@
> return paircompare( req, first, second, NULL, NULL );
> }
>
> +/*
> + * Compare ONE attribute from a (potential) list.
> + * Return the first matching one.
> + */
> +
> +static VALUE_PAIR * paircmpmatchone(REQUEST *req, VALUE_PAIR *first, VALUE_PAIR *second)
> +{
> + VALUE_PAIR *fnext = NULL;
> + VALUE_PAIR *snext = NULL;
> + int result = 0;
> +
> + for(; second; second = second->next){
> + for(; first; first = first->next){
> + if(first->attribute == second->attribute){
> + /* No matter what, compare only THESE items in chain */
> + fnext = first->next;
> + first->next = NULL;
> + snext = second->next;
> + second->next = NULL;
> + result = paircompare(req,first,second,NULL,NULL);
> + first->next = fnext;
> + second->next = snext;
> +
> + if(!result)
> + return first;
> + }
> + }
> + }
> + return NULL;
> +}
>
> +#ifdef HAVE_REGEX_H
> +/*
> + * Regex Compare ONE attribute from a (potential) list.
> + * Return the first matching one.
> + */
> +
> +static VALUE_PAIR * pairregmatchone(REQUEST *req, VALUE_PAIR *first, VALUE_PAIR *second)
> +{
> + int result = 0;
> + regex_t reg;
> +
> + for(; second; second = second->next){
> + for(; first; first = first->next){
> + if(first->attribute == second->attribute) {
> + if (second->operator == T_OP_REG_EQ ||
> + second->operator == T_OP_REG_NE ||
> + second->operator == T_OP_SUB_REG)
> + {
> + regcomp(®, (char *)second->vp_strvalue,
> + REG_EXTENDED);
> + result = regexec(®, (char *)first->vp_strvalue,
> + 0, NULL, 0);
> + regfree(®);
> +
> + if(!result)
> + return first;
> + }
> + if (first->operator == T_OP_REG_EQ ||
> + first->operator == T_OP_REG_NE ||
> + first->operator == T_OP_SUB_REG)
> + {
> +
> + regcomp(®, (char *)first->vp_strvalue,
> + REG_EXTENDED);
> + result = regexec(®, (char *)second->vp_strvalue,
> + 0, NULL, 0);
> + regfree(®);
> +
> + if(!result)
> + return second;
> + }
> + }
> + }
> + }
> + return NULL;
> +}
> +#endif
> +
> +/*
> + * Deletes matching attributes.
> + */
> +static void pairdeletematch(REQUEST *req,VALUE_PAIR **first,VALUE_PAIR *second)
> +{
> + VALUE_PAIR *vp, *i;
> +
> + while((vp = paircmpmatchone(req,*first,second))){
> + if(*first == vp) /* new head of chain */
> + *first = vp->next;
> + else
> + for(i = *first; i; i = i->next){
> + if(i->next == vp){ /* dis-own */
> + i->next = vp->next;
> + break;
> + }
> + }
> + pairbasicfree(vp);
> + }
> +}
> +
> +#ifdef HAVE_REGEX_H
> +/*
> + * deletes matching regex pairs
> +*/
> +static void pairdeleteregmatch(REQUEST *req,VALUE_PAIR **first,VALUE_PAIR *second)
> +{
> + VALUE_PAIR *vp, *i;
> +
> + while((vp = pairregmatchone(req,*first,second))){
> + if(*first == vp) /* new head of chain */
> + *first = vp->next;
> + else
> + for(i = *first; i; i = i->next){
> + if(i->next == vp){ /* dis-own */
> + i->next = vp->next;
> + break;
> + }
> + }
> + pairbasicfree(vp);
> + }
> +}
> +#endif
> /*
> * Move pairs, replacing/over-writing them, and doing xlat.
> */
> @@ -485,6 +606,7 @@
> * Point "tailto" to the end of the "to" list.
> */
> tailto = to;
> +
> for(i = *to; i; i = i->next) {
> tailto = &i->next;
> }
> @@ -525,30 +647,57 @@
> switch (i->operator) {
>
> /*
> - * If a similar attribute is found,
> - * delete it.
> + * If a similar attribute are found,
> + * delete them.
> */
> case T_OP_SUB: /* -= */
> if (found) {
> - if (!i->vp_strvalue[0] ||
> - (strcmp((char *)found->vp_strvalue,
> - (char *)i->vp_strvalue) == 0)){
> - pairdelete(to, found->attribute);
> -
> - /*
> - * 'tailto' may have been
> - * deleted...
> - */
> + if (!i->vp_strvalue[0])
> + goto delete_all;
> +
> + pairdeletematch(req,to,i);
> + /*
> + * 'tailto' may have been
> + * deleted...
> + */
> + tailto = to;
> + for(j = *to; j; j = j->next) {
> + tailto = &j->next;
> + }
> +
> + }
> + tailfrom = i;
> + continue;
> + break;
> + case T_OP_SUB_ALL: /* -* */
> + if (found) {
> +delete_all:
> + pairdelete(to, found->attribute);
> tailto = to;
> for(j = *to; j; j = j->next) {
> tailto = &j->next;
> }
> - }
> }
> tailfrom = i;
> continue;
> break;
>
> +#ifdef HAVE_REGEX_H
> + case T_OP_SUB_REG: /* -~ */
> + if (found) {
> +
> + pairdeleteregmatch(req,to,i);
> +
> + tailto = to;
> + for(j = *to; j; j = j->next) {
> + tailto = &j->next;
> + }
> +
> + tailfrom = i;
> + continue;
> + break;
> + }
> +#endif
> /*
> * Add it, if it's not already there.
> */
>
>
> ------------------------------------------------------------------------
>
> diff -ur radiusd/src/modules/rlm_policy/evaluate.c freeradius-1.1.0/src/modules/rlm_policy/evaluate.c
> --- radiusd/src/modules/rlm_policy/evaluate.c 2005-09-27 19:59:11.000000000 -0400
> +++ freeradius-1.1.0/src/modules/rlm_policy/evaluate.c 2005-10-12 13:09:21.000000000 -0400
> @@ -344,13 +342,15 @@
> rad_assert(pitem != NULL);
> rad_assert(state->depth >= 0);
>
> - redo:
> +redo:
> if (state->depth == 0) {
> *pitem = NULL;
> return 0;
> }
>
> *pitem = state->stack[state->depth - 1];
> + if(state->depth > 1)
> + state->depth--;
>
> /*
> * Named policies are on the stack for catching recursion.
> @@ -490,7 +490,7 @@
> {
> int rcode;
> const policy_condition_t *this;
> - VALUE_PAIR *vp;
> + VALUE_PAIR *vp = NULL;
> const char *data = NULL;
> int compare;
> #ifdef HAVE_REGEX_H
> @@ -498,6 +498,7 @@
> #endif
> char buffer[256];
> char lhs_buffer[2048];
> + int next_vp = 0;
>
> this = (const policy_condition_t *) item;
>
> @@ -533,7 +534,9 @@
> rcode = evaluate_condition(state, this->child);
> rcode = (rcode == FALSE); /* reverse sense of test */
> break;
> -
> +
> + case POLICY_LEX_CMP_FALSE: /* no existence */
> + /*fall through*/
> case POLICY_LEX_CMP_TRUE: /* existence */
> if (this->lhs_type == POLICY_LEX_BARE_WORD) {
> vp = find_vp(state->request, this->lhs);
> @@ -541,6 +544,8 @@
> } else {
> rcode = (data != NULL);
> }
> + if (this->compare == POLICY_LEX_CMP_FALSE)
> + rcode = !rcode;
> break;
>
> default: /* process other comparisons */
> @@ -561,9 +566,15 @@
>
> if (this->lhs_type == POLICY_LEX_BARE_WORD) {
> VALUE_PAIR *myvp;
> + vp = find_vp(state->request, this->lhs);
> +retry_next_vp:
> + if(vp && next_vp)
> + {
> + const DICT_ATTR *dattr = dict_attrbyname(vp->name);
> + vp = pairfind(vp, dattr->attr);
> + }
>
>
> - vp = find_vp(state->request, this->lhs);
> /*
> * FIXME: Move sanity checks to
> * post-parse code, so we don't do
> @@ -638,6 +649,12 @@
> int i;
> regmatch_t rxmatch[REQUEST_MAX_REGEX + 1];
>
> + /* attribute is not in request */
> + if (compare == -1) {
> + rcode = FALSE;
> + break;
> + }
> +
> /*
> * Include substring matches.
> */
> @@ -646,6 +663,7 @@
> return FALSE;
> }
> rad_assert(data != NULL);
> +
> rcode = regexec(®, data,
> REQUEST_MAX_REGEX + 1,
> rxmatch, 0);
> @@ -720,6 +738,11 @@
> } /* switch over comparison operators */
> break; /* default from first switch over compare */
> }
> + if (rcode == FALSE && (vp = vp->next))
> + {
> + next_vp = 1;
> + goto retry_next_vp;
> + }
>
> /*
> * No trailing &&, ||
> @@ -814,6 +837,19 @@
> case POLICY_LEX_PLUS_EQUALS:
> operator = T_OP_ADD;
> break;
> +
> + case POLICY_LEX_MINUS_EQUALS:
> + operator = T_OP_SUB;
> + break;
> +
> + case POLICY_LEX_MINUS_TRUE:
> + operator = T_OP_SUB_ALL;
> + break;
> +
> + case POLICY_LEX_RX_MINUS:
> + operator = T_OP_SUB_REG;
> + break;
> +
>
> default:
> fprintf(stderr, "Expected '=' for operator, not '%s' at line %d\n",
> @@ -898,12 +934,12 @@
> break;
>
> case POLICY_LEX_ASSIGN: /* 'union' */
> - pairmove(vps, &head);
> + pairxlatmove(NULL, vps, &head);
> pairfree(&head);
> break;
>
> case POLICY_LEX_CONCAT_EQUALS:
> - pairadd(vps, head);
> + pairxlatmove(NULL, vps, &head);
> break;
>
> default:
> diff -ur radiusd/src/modules/rlm_policy/parse.c freeradius-1.1.0/src/modules/rlm_policy/parse.c
> --- radiusd/src/modules/rlm_policy/parse.c 2005-10-10 06:41:37.000000000 -0400
> +++ freeradius-1.1.0/src/modules/rlm_policy/parse.c 2005-10-12 06:46:38.000000000 -0400
> @@ -97,6 +97,8 @@
> { "!", POLICY_LEX_L_NOT },
> { "=", POLICY_LEX_ASSIGN },
> { "==", POLICY_LEX_CMP_EQUALS },
> + { "=*", POLICY_LEX_CMP_TRUE },
> + { "!*", POLICY_LEX_CMP_FALSE },
> { "!=", POLICY_LEX_CMP_NOT_EQUALS },
> { "<", POLICY_LEX_LT },
> { ">", POLICY_LEX_GT },
> @@ -106,6 +108,9 @@
> { "!~", POLICY_LEX_RX_NOT_EQUALS },
> { ".=", POLICY_LEX_CONCAT_EQUALS },
> { ":=", POLICY_LEX_SET_EQUALS },
> + { "-=", POLICY_LEX_MINUS_EQUALS },
> + { "-*", POLICY_LEX_MINUS_TRUE },
> + { "-~", POLICY_LEX_RX_MINUS },
> { "double quoted string", POLICY_LEX_DOUBLE_QUOTED_STRING },
> { "single quoted string", POLICY_LEX_SINGLE_QUOTED_STRING },
> { "back quoted string", POLICY_LEX_BACK_QUOTED_STRING },
> @@ -190,6 +195,16 @@
> *token = POLICY_LEX_MINUS_EQUALS;
> input++;
> break;
> +
> + case '*':
> + *token = POLICY_LEX_MINUS_TRUE;
> + input++;
> + break;
> +
> + case '~':
> + *token = POLICY_LEX_RX_MINUS;
> + input++;
> + break;
>
> default:
> *token = POLICY_LEX_MINUS;
> @@ -699,8 +714,8 @@
> lrad_int2str(rlm_policy_tokens, token, "?"));
> return 0;
> }
> - goto check;
> } /* else it's a comparison? */
> + goto check;
>
> case POLICY_LEX_DOUBLE_QUOTED_STRING:
> this->lhs_type = token;
> @@ -727,6 +742,8 @@
> case POLICY_LEX_GT:
> case POLICY_LEX_LE:
> case POLICY_LEX_GE:
> + case POLICY_LEX_CMP_TRUE:
> + case POLICY_LEX_CMP_FALSE:
> break;
>
> default:
> @@ -1231,6 +1248,9 @@
> case POLICY_LEX_AND_EQUALS:
> case POLICY_LEX_OR_EQUALS:
> case POLICY_LEX_PLUS_EQUALS:
> + case POLICY_LEX_MINUS_EQUALS:
> + case POLICY_LEX_MINUS_TRUE:
> + case POLICY_LEX_RX_MINUS:
> break;
>
> default:
> diff -ur radiusd/src/modules/rlm_policy/rlm_policy.h freeradius-1.1.0/src/modules/rlm_policy/rlm_policy.h
> --- radiusd/src/modules/rlm_policy/rlm_policy.h 2005-10-10 06:41:39.000000000 -0400
> +++ freeradius-1.1.0/src/modules/rlm_policy/rlm_policy.h 2005-10-12 13:10:15.000000000 -0400
> @@ -37,6 +37,7 @@
>
> #include "rad_assert.h"
>
> +
> /*
> * Internal lexer.
> */
> @@ -74,6 +75,8 @@
> POLICY_LEX_OR_EQUALS, /* |= */
> POLICY_LEX_PLUS_EQUALS, /* += */
> POLICY_LEX_MINUS_EQUALS, /* -= */
> + POLICY_LEX_MINUS_TRUE, /* -* */
> + POLICY_LEX_RX_MINUS, /* -~*/
> POLICY_LEX_CONCAT_EQUALS, /* .= */
> POLICY_LEX_VARIABLE, /* %{foo} */
> POLICY_LEX_FUNCTION, /* Hmmm... */
> --- radiusd/raddb/policy.txt 2004-12-16 17:21:41.000000000 -0500
> +++ freeradius-1.1.0/raddb/policy.txt 2005-10-10 08:19:48.000000000 -0400
> @@ -67,5 +67,5 @@
> #
> # Execute "3pm", as if it was in-line here.
> #
> -# call 3pm
> + 3pm()
> }
>
>
> ------------------------------------------------------------------------
>
> debug print_tokens # as we're parsing this file
> debug print_policy # once the file has been parsed
> debug evaluate # print limited information during evaluation
>
>
> policy pool_conflict_ipaddr {
> if ( (proxy-reply:Framed-IP-Address =* "") && (reply:Cisco-Avpair =~ "ip:addr-pool.*")) {
> reply .= {
> Cisco-Avpair -~ "ip:addr-pool.*"
> }
> }
> }
>
>
> policy post-proxy {
>
> pool_conflict_ipaddr()
> }
>
>
>
>
> ------------------------------------------------------------------------
>
> -
> List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
More information about the Freeradius-Devel
mailing list