Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Problem with Net::LDAP::Control::Paged and Oracle Internet Directory

52 views
Skip to first unread message

Chris Ridd

unread,
Jan 19, 2012, 7:12:05 AM1/19/12
to John Devitofranceschi, perl...@perl.org

On 19 Jan 2012, at 01:35, John Devitofranceschi wrote:

> I am trying to use a slightly modified version of the Net::LDAP example
> scripts with paging and callbacks against Oracle Internet directory.
>
> I am using perl 5.14.2 and very fresh versions of all the CPAN modules.
>
> The script fails with:
>
> LDAP Search Failed: decode error 22 75 at
> /run/pd/csm/64-bit/cpan/5.14.2-2011.11/lib/Convert/ASN1/_decode.pm line
> 233, <DATA> line 522.
>
> And yet, a paged openldap ldapsearch works just fine (with "-E
> !pr=10/noprompt").
>
> If I strip out the paging code, the script works, but I really need to
> be able to use that extension.
>
> Here's the code:
> ...
> my $page = Net::LDAP::Control::Paged->new( size => 2 ); # keeping the size small for illus. purposes
> my @args = ( base => $base,
> scope => 'sub',
> filter => $query,
> attrs => \@attrs,
> callback => \&callback,
> control => [ $page ] );
>
>
> my $cookie;
> my $i = 1;
> while(1) {
> $ldap->debug(2);
> my $search = $ldap->search(@args);
>
> $search->code and do {
> exit print "LDAP Search Failed: " . $search->error . "\n";
> }
> ...
>
> }
> ...
>
>
> Running the script yields:
>
> Net::LDAP=HASH(0x10085c170) sending:
> Net::LDAP=HASH(0x10085c170) received:
>
> *an entry dump in hex*
>
> dn: *dn of an entry*
> Net::LDAP=HASH(0x10085c170) received:
>
> *anonther entry dump in hex*
>
> dn: *dn of another entry*
> Net::LDAP=HASH(0x10085c170) received:
>
> 30 84 00 00 00 45 02 01 01 65 84 00 00 00 3C 0A 0....E...e....<.
> 01 00 04 00 04 00 A0 84 00 00 00 2F 30 84 00 00 .........../0...
> 00 29 04 16 31 2E 32 2E 38 34 30 2E 31 31 33 35 .)..1.2.840.1135
> 35 36 2E 31 2E 34 2E 33 31 39 01 01 00 04 0C 30 56.1.4.319.....0
> 0A 02 01 00 04 05 35 31 61 32 66 __ __ __ __ __ ......51a2f
>
> LDAP Search Failed: decode error 22 75 at
> /run/pd/csm/64-bit/cpan/5.14.2-2011.11/lib/Convert/ASN1/_decode.pm line 233, <DATA> line 522.
>
>
> Is there a known issue with Oracle Internet Directory?

Not as far as I know, but perhaps no-one has tried this combination out much.

You've elided some code - I take it the elided code sets the page cookie as per the man page example?

A decode of the last received packet looks like this:

0 69: SEQUENCE {
6 1: INTEGER 1
9 60: [APPLICATION 5] {
15 1: ENUMERATED 0
18 0: OCTET STRING
20 0: OCTET STRING
22 47: [0] {
28 41: SEQUENCE {
34 22: OCTET STRING '1.2.840.113556.1.4.319'
58 1: BOOLEAN FALSE
61 12: OCTET STRING 30 0A 02 01 00 04 05 35 31 61 32 66
: }
: }
: }
: }

(Output from dumpasn1 -z -e.)

In other words, it is an LDAPMessage with messageID 1 and a SearchResultDone ([APPLICATION 5] { ... }) and a sequence of Controls ([0] { ... }).

However, the nesting is wrong - the Controls (starting at byte 22) are being encoded inside the SearchResultDone. That's not correct - they should be in the outer LDAPMessage instead. Something like this:

: SEQUENCE {
: INTEGER 1
: [APPLICATION 5] {
: ENUMERATED 0
: OCTET STRING
: OCTET STRING
: }
: [0] {
: SEQUENCE {
: OCTET STRING '1.2.840.113556.1.4.319'
: BOOLEAN FALSE
: OCTET STRING 30 0A 02 01 00 04 05 35 31 61 32 66
: }
: }
: }

I think Oracle's sending bad protocol back.

However I don't /think/ we should be barfing like that, as LDAP has built-in extensibility rules which state that clients/servers should try to ignore bits of unexpected data as long as they're in the "right place". IIRC you can put in custom stuff but only at the ends of certain structures and we should just ignore it. But even if we ignored it, we still wouldn't find Oracle's misplaced paged results control :-(

Two bugs for the price of one!

Chris

Chris Ridd

unread,
Jan 19, 2012, 8:21:41 AM1/19/12
to John Devitofranceschi, perl...@perl.org

On 19 Jan 2012, at 12:39, John Devitofranceschi wrote:

> Two bugs! Such a deal!

No extra charge :-)

> Yes, the cookie setting code is in the while (1) loop and the callback merely prints out the dn of the returned entries.

You mentioned that the OpenLDAP ldapsearch command-line tool seemed to work. Can you double-check it is getting multiple pages back (try using pr=2/prompt), or whether it is stopping after the first page because of the misplaced result cookie?

The only other difference I can see between your ldapsearch args and your Net::LDAP code is that the control's criticality is different. Does varying that affect things?

> Thanks very much for the quick analysis. I'll need to add dumpasn1 to my bag of tricks!

You can get Net::LDAP to output something similar to dumpasn1's using $ldap->debug(8). The value is a bitmask, and the bits are described in the Net::LDAP man page. But dumpasn1 is a handy tool to have around anyway.

Cheers,

Chris

John Devitofranceschi

unread,
Jan 19, 2012, 9:00:22 AM1/19/12
to Chris Ridd, perl...@perl.org


On Jan 19, 2012, at 8:21, Chris Ridd <chri...@mac.com> wrote:

>
> On 19 Jan 2012, at 12:39, John Devitofranceschi wrote:
>
>> Two bugs! Such a deal!
>
> No extra charge :-)
>
>> Yes, the cookie setting code is in the while (1) loop and the callback merely prints out the dn of the returned entries.
>
> You mentioned that the OpenLDAP ldapsearch command-line tool seemed to work. Can you double-check it is getting multiple pages back (try using pr=2/prompt), or whether it is stopping after the first page because of the misplaced result cookie?

OpenLDAP's ldapsearch works as expected. Multiple pages get returned.

>
> The only other difference I can see between your ldapsearch args and your Net::LDAP code is that the control's criticality is different. Does varying that affect things?

Changing the criticality makes no difference in either case. It either continues to work in the ldapsearch case or continues to fail in the perl-ldap case.

>
>> Thanks very much for the quick analysis. I'll need to add dumpasn1 to my bag of tricks!
>
> You can get Net::LDAP to output something similar to dumpasn1's using $ldap->debug(8). The value is a bitmask, and the bits are described in the Net::LDAP man page. But dumpasn1 is a handy tool to have around anyway.
>
> Cheers,
>
> Chris

Thanks again,
jd

Chris Ridd

unread,
Jan 19, 2012, 9:05:08 AM1/19/12
to John Devitofranceschi, perl...@perl.org

On 19 Jan 2012, at 14:00, John Devitofranceschi wrote:

>
>
> On Jan 19, 2012, at 8:21, Chris Ridd <chri...@mac.com> wrote:
>
>>
>> On 19 Jan 2012, at 12:39, John Devitofranceschi wrote:
>>
>>> Two bugs! Such a deal!
>>
>> No extra charge :-)
>>
>>> Yes, the cookie setting code is in the while (1) loop and the callback merely prints out the dn of the returned entries.
>>
>> You mentioned that the OpenLDAP ldapsearch command-line tool seemed to work. Can you double-check it is getting multiple pages back (try using pr=2/prompt), or whether it is stopping after the first page because of the misplaced result cookie?
>
> OpenLDAP's ldapsearch works as expected. Multiple pages get returned.

That's puzzling, and suggests my analysis is wrong. Can you get some (snoop/tcpdump) packet traces from ldapsearch and perl up to and including the first page search done? It'll have passwords and your data in so if you want to send them off-list that's fine.

Chris

Chris Ridd

unread,
Jan 19, 2012, 3:16:11 PM1/19/12
to John Devitofranceschi, perl...@perl.org
Just to follow up on-list - the snoops that John sent me both showed that Oracle consistently sends the paged results control in the wrong place. Wireshark also complained.

Unless Oracle's shipping a version of ldapsearch that reads the control from the wrong place and counteracts their server bug, I'm puzzled how John's ldapsearch works.

Chris

John Devitofranceschi

unread,
Jan 19, 2012, 3:44:14 PM1/19/12
to Chris Ridd, perl...@perl.org
Actually, that ldapsearch is from Openldap on Redhat Linux.
0 new messages