Hi, I just read in a post where Phil Mayers commented on some much needed (imho) functionality of FR. Maybe it's in there and I don't know, but he added in multivalue attribute comparisons :
* |== At least one attribute should equal the value * &== All attributes should equal the value * |=~ At least one attribute should match the regular expression * &=~ All attributes should match the regular expression
This would help me in my random thrashing of the ldap servers to check against lots of groups - I already populate a multivalue attributes "Ldap-MemberOf" and this would let me test against it nicely without foreach. Problem is that it doesn't work now: .. |== .. ^ Invalid text. Expected comparison operator Has it been removed from recent releases, and if so, how can I get it back ? Thanks Andy
Franks Andy (RLZ) IT Systems Engineer wrote:
This would help me in my random thrashing of the ldap servers to check against lots of groups
Use v3. It caches LDAP group checking. And you can use "foreach" to check multi-valued attributes.
– I already populate a multivalue attributes “Ldap-MemberOf” and this would let me test against it nicely without foreach. Problem is that it doesn’t work now:
.. |== ..
^ Invalid text. Expected comparison operator
Has it been removed from recent releases, and if so, how can I get it back ?
The operator "|==" never existed in the server code. Alan DeKok.
On 28/07/14 17:04, Franks Andy (RLZ) IT Systems Engineer wrote:
Hi,
I just read in a post where Phil Mayers commented on some much needed (imho) functionality of FR. Maybe it’s in there and I don’t know, but he added in multivalueattributecomparisons :
I don't *think* that was me - I recall someone else in the thread suggesting that. My "contribution" was to comment on the historical behaviour of =~ which is now gone.
/* |== At least one attribute should equal the value/
/* &== All attributes should equal the value/
/* |=~ At least one attribute should match the regular expression/
/* &=~ All attributes should match the regular expression///
This would help me in my random thrashing of the ldap serversto check against lots of groups–Ialready populate a multivalueattributes“Ldap-MemberOf” and this would let me test against it nicely without foreach. Problem is that it doesn’t work now:
.. |== ..
^ Invalid text. Expected comparison operator
Has it been removed from recent releases, and if so, how can I get it back ?
As far as I know, it was only ever a suggestion someone made. It's never worked.
On 28 Jul 2014, at 12:23, Phil Mayers <p.mayers@imperial.ac.uk> wrote:
On 28/07/14 17:04, Franks Andy (RLZ) IT Systems Engineer wrote:
Hi,
I just read in a post where Phil Mayers commented on some much needed (imho) functionality of FR. Maybe it’s in there and I don’t know, but he added in multivalueattributecomparisons :
I don't *think* that was me - I recall someone else in the thread suggesting that. My "contribution" was to comment on the historical behaviour of =~ which is now gone.
/* |== At least one attribute should equal the value/
/* &== All attributes should equal the value/
/* |=~ At least one attribute should match the regular expression/
/* &=~ All attributes should match the regular expression///
This would help me in my random thrashing of the ldap serversto check against lots of groups–Ialready populate a multivalueattributes“Ldap-MemberOf” and this would let me test against it nicely without foreach. Problem is that it doesn’t work now:
.. |== ..
^ Invalid text. Expected comparison operator
Has it been removed from recent releases, and if so, how can I get it back ?
As far as I know, it was only ever a suggestion someone made. It's never worked.
I think it was probably Olivier. My inclination is to make '==' work as it used to in the users file and iterate over all instances of an attribute. Then use attribute selectors [<inst>] :<tag> to limit the attribute used in the condition. if (&foo == &bar) { } Would apply the operator to the cartesian product of &foo x &bar. But I think this is too much of a major change to make in 3.0.x, maybe 3.1... What do others think? -Arran Arran Cudbard-Bell <a.cudbardb@freeradius.org> FreeRADIUS development team FD31 3077 42EC 7FCD 32FE 5EE2 56CF 27F9 30A8 CAA2
On 28/07/2014 17:41, Arran Cudbard-Bell wrote:
My inclination is to make '==' work as it used to in the users file and iterate over all instances of an attribute.
"and" or "or" semantics?
Then use attribute selectors [<inst>] :<tag> to limit the attribute used in the condition.
if (&foo == &bar) {
}
Would apply the operator to the cartesian product of &foo x &bar.
I can't say that particular syntax appeals to me. Postgres uses "any / all" for this, e.g. expr op [any|all] array-expr ...though I guess for consistency FR should be: expr op [first|any|all] multi-attr ...with "first" being the current behaviour?
On 29 Jul 2014, at 03:15, Phil Mayers <p.mayers@IMPERIAL.AC.UK> wrote:
On 28/07/2014 17:41, Arran Cudbard-Bell wrote:
My inclination is to make '==' work as it used to in the users file and iterate over all instances of an attribute.
"and" or "or" semantics?
or
Then use attribute selectors [<inst>] :<tag> to limit the attribute used in the condition.
if (&foo == &bar) {
}
Would apply the operator to the cartesian product of &foo x &bar.
I can't say that particular syntax appeals to me.
Postgres uses "any / all" for this, e.g.
expr op [any|all] array-expr
...though I guess for consistency FR should be:
expr op [first|any|all] multi-attr
...with "first" being the current behaviour?
Sure... Though We already use [*] for string expansions, Alan suggested using the same here to refer to multiple instances. Do you think that'd work ok? Arran Cudbard-Bell <a.cudbardb@freeradius.org> FreeRADIUS development team FD31 3077 42EC 7FCD 32FE 5EE2 56CF 27F9 30A8 CAA2
On 29 Jul 2014, at 12:11, Phil Mayers <p.mayers@IMPERIAL.AC.UK> wrote:
On 29/07/2014 15:45, Arran Cudbard-Bell wrote:
Sure... Though We already use [*] for string expansions, Alan suggested using the same here to refer to multiple instances. Do you think that'd work ok?
Not sure I understand. As in:
if (Attr[*] =~ /regex/)
Yes, where each instance of attr would be checked against the regex, and if any matched the condition would be true. Arran Cudbard-Bell <a.cudbardb@freeradius.org> FreeRADIUS development team FD31 3077 42EC 7FCD 32FE 5EE2 56CF 27F9 30A8 CAA2
On 29-07-14 19:44, Arran Cudbard-Bell wrote:
On 29 Jul 2014, at 12:11, Phil Mayers <p.mayers@IMPERIAL.AC.UK> wrote:
On 29/07/2014 15:45, Arran Cudbard-Bell wrote:
Sure... Though We already use [*] for string expansions, Alan suggested using the same here to refer to multiple instances. Do you think that'd work ok?
Not sure I understand. As in:
if (Attr[*] =~ /regex/)
Yes, where each instance of attr would be checked against the regex, and if any matched the condition would be true.
What would the semantics be if a negative comparison operator would be used, like this? if (Attr[*] !~ /regex/) My intuition would say this would only be true if none of the attributes matches, instead of if at least one of the attributes matches. And I'm not sure what the expected result should be in the following statement: if (Attr[*] > 10) -- Herwin Weststrate
On 30/07/14 09:21, Herwin Weststrate wrote:
What would the semantics be if a negative comparison operator would be used, like this?
if (Attr[*] !~ /regex/)
My intuition would say this would only be true if none of the attributes matches, instead of if at least one of the attributes matches.
Assuming I've understood correctly, using the analogy of the postgres operator, this is more like: if (any Attr !~ /regex/) i.e. if any of the attributes *don't* match. The regex operators would presumably have the special behaviour of setting capture groups for the first of the attributes. This doesn't have much meaning for !~
And I'm not sure what the expected result should be in the following statement:
if (Attr[*] > 10)
Likewise if (any Attr > 10)
On 30-07-14 11:51, Phil Mayers wrote:
On 30/07/14 09:21, Herwin Weststrate wrote:
What would the semantics be if a negative comparison operator would be used, like this?
if (Attr[*] !~ /regex/)
My intuition would say this would only be true if none of the attributes matches, instead of if at least one of the attributes matches.
Assuming I've understood correctly, using the analogy of the postgres operator, this is more like:
if (any Attr !~ /regex/)
i.e. if any of the attributes *don't* match.
That would make the following two expressions different: if (Attr[*] !~ /regex/) if (!(Attr[*] =~ /regex/)) First one is true if any of the attributes doesn't match the regex, the second one if none of the attribute match the regex. I would expect them to return the same. There might be some rule or lemma in mathematical set theory here, but I'm not really sure about that (especially since that would probably require explicit any/all-modifiers).
The regex operators would presumably have the special behaviour of setting capture groups for the first of the attributes. This doesn't have much meaning for !~
Using capture groups with !~ would require an else (because if the regex doesn't match, there are no capture groups). Using code like that would just be stupid: if (Attr !~ /(regex)/) { ... } else { # Do someting with %{1} } Just write it a little bit different and use =~. But this discussion is not really related to multivalued attributes.
And I'm not sure what the expected result should be in the following statement:
if (Attr[*] > 10)
Likewise
if (any Attr > 10)
This gives the same behaviour as with !~, I would expect these two to be the same if (Attr[*] > 10) if (!(Attr[*] <= 9)) About a year ago I was working on a small filtering language for an API which required multi-valued attributes. We changed the use of >, <, <= and >= to yield to syntax errors when combined with multi-valued attributes, because nobody here really knew what they were supposed to do in this context. -- Herwin Weststrate
Herwin Weststrate wrote:
That would make the following two expressions different:
if (Attr[*] !~ /regex/) if (!(Attr[*] =~ /regex/))
In general, != and !~ should be the same as !(.. == ) and !(.. =~)
First one is true if any of the attributes doesn't match the regex, the second one if none of the attribute match the regex. I would expect them to return the same. There might be some rule or lemma in mathematical set theory here, but I'm not really sure about that (especially since that would probably require explicit any/all-modifiers).
I'll try to remember my math. I'm sure I had this in one of my degrees.
About a year ago I was working on a small filtering language for an API which required multi-valued attributes. We changed the use of >, <, <= and >= to yield to syntax errors when combined with multi-valued attributes, because nobody here really knew what they were supposed to do in this context.
Makes sense. Alan DeKok.
On 31 Jul 2014, at 04:33, Alan DeKok <aland@deployingradius.com> wrote:
Herwin Weststrate wrote:
That would make the following two expressions different:
if (Attr[*] !~ /regex/) if (!(Attr[*] =~ /regex/))
In general, != and !~ should be the same as !(.. == ) and !(.. =~)
I don't think that's correct in this case. != is equivalent to attrA ⊄ attrB == is equivalent to attrA ⊆ attrB ! is a completely different operator (logical NOT), so I don't see it as being an issue that those two expressions aren't equivalent. It'd be great to use the proper set operators everywhere in FreeRADIUS, but I imagine the majority of users wouldn't have a clue what they meant. So we do the automatic translation based on the types of the operands. We already translate < to mean subset when applying to IP ranges. i.e. 192.168.0.1 < 192.168.0.0/24 Is true. I see this as another case of needing to do the implicit conversion from well known comparison operators to set theory operators.
First one is true if any of the attributes doesn't match the regex, the second one if none of the attribute match the regex. I would expect them to return the same. There might be some rule or lemma in mathematical set theory here, but I'm not really sure about that (especially since that would probably require explicit any/all-modifiers).
I'll try to remember my math. I'm sure I had this in one of my degrees.
I didn't cover it when I studied set theory, but that was really set theory light.
About a year ago I was working on a small filtering language for an API which required multi-valued attributes. We changed the use of >, <, <= and >= to yield to syntax errors when combined with multi-valued attributes, because nobody here really knew what they were supposed to do in this context.
Makes sense.
You can apply the same logic I described previously to any operator, and you'll get consistent and understandable results. Arran Cudbard-Bell <a.cudbardb@freeradius.org> FreeRADIUS development team FD31 3077 42EC 7FCD 32FE 5EE2 56CF 27F9 30A8 CAA2
On 29/07/14 18:44, Arran Cudbard-Bell wrote:
if (Attr[*] =~ /regex/)
Yes, where each instance of attr would be checked against the regex, and if any matched the condition would be true.
FWIW "*" to me says "all" and implies "and", not "or" semantics. However, I think we are (well, I am ;o) probably well into bikeshedding here. No syntax will satisfy everyone. I guess use whatever is easiest to integrate into unlang parsing and can perform well.
participants (5)
-
Alan DeKok -
Arran Cudbard-Bell -
Franks Andy (RLZ) IT Systems Engineer -
Herwin Weststrate -
Phil Mayers