inejge / ldap3

A pure-Rust LDAP library using the Tokio stack
Apache License 2.0
220 stars 38 forks source link

[RFC] Implement rfc3876 (Matched Values) #64

Closed Geobert closed 3 years ago

Geobert commented 3 years ago

Hi there,

We are in the need of Matched Values Control and it's not available in ldap3.

RFC https://tools.ietf.org/html/rfc3876.html

Would you mind if we add it?

Regards,

inejge commented 3 years ago

Go ahead, by all means. Please reuse as much of src/filter.rs as possible; ideally, your filter parsing should extend the code in that file. I believe almost everything you need is already there.

Geobert commented 3 years ago

It seems that there's already everything in src/filter.rs so the control is basically calling parse and instantiate a RawControl with the matched values control's OID :)

correct me if I'm wrong :D

inejge commented 3 years ago

The top-level filter expression in the Matched Values control lacks the logical operator (it's an implicit "or") and its encoding is different, so you can't use the filter production as-is. Try passing a valid multi-element M-V filter to parse_filter() and you'll get a parse error back. I believe you can fully reuse the item production.

Geobert commented 3 years ago

Thanks for you insight :)

What is "M-V"?

inejge commented 3 years ago

What is "M-V"?

"Matched Values".

Geobert commented 3 years ago

I need a bit of help here.

So far I got this grammar:

named!(filtexpr<Tag>, alt!(filter | valuesreturnfilter | item));

named!(
    valuesreturnfilter<Tag>,
    delimited!(char!('('), itemlist, char!(')'))
);
named!(valuesreturnfilterlist<Vec<Tag>>, many1!(valuesreturnfilter));
named!(
    itemlist<Tag>,
    map!(valuesreturnfilterlist, |tagv: Vec<Tag>| -> Tag {
        Tag::Sequence(Sequence {
            class: TagClass::Universal,
            id: lber::universal::Types::Sequence as u64,
            inner: tagv,
        })
    })
);

but it fails to parse "((attr=val*))" and I don't get why.

It does succeed to parse "(attr=val*)" though (but the encoding seems wrong, which is another issue)

EDIT: I got something that parse the problematic expr:

named!(
    valuesreturnfilter<Tag>,
    delimited!(char!('('), item_or_list, char!(')'))
);
named!(valuesreturnfilterlist<Vec<Tag>>, many1!(valuesreturnfilter));
named!(item_or_list<Tag>, alt!(itemlist | item));
named!(
    itemlist<Tag>,
    map!(valuesreturnfilterlist, |tagv: Vec<Tag>| -> Tag {
        Tag::Sequence(Sequence {
            class: TagClass::Universal,
            id: lber::universal::Types::Sequence as u64,
            inner: tagv,
        })
    })
);
inejge commented 3 years ago

See the final version (817c5124 in the v07x branch) for the form of the grammar.