LDAP PagedResults ControlType Incompatible #27

Open
strich opened this Issue Jan 17, 2012 · 16 comments

Projects

None yet

8 participants

@strich
strich commented Jan 17, 2012

I'm currently developing an application internally at IBM and their LDAP server fails to successfully search with the hard-coded ControlType in Net::LDAP, here: https://github.com/ruby-ldap/ruby-net-ldap/blob/master/lib/net/ldap.rb#L339

I meant to just write up a patch for this but it looks like it is much more involved that I originally thought. The IBM LDAP server, whatever it is, appears to support ControlType 2.16.840.1.113730.3.4.2 (RFC 3296).

When substituted with the hard-coded one in PagedResults, it works fine.

Happy to supply wireshark dumps, etc whatever to help out. Let me know.

@garbagecat
Collaborator

Scott, with reference to the line of code that you quoted, are you
saying that your app works correctly if you simply change the OID to
2,16,840.1.113730.3.4.2?

On 01/16/2012 10:23 PM, Scott Richmond wrote:

I'm currently developing an application internally at IBM and their LDAP server fails to successfully search with the hard-coded ControlType in Net::LDAP, here: https://github.com/ruby-ldap/ruby-net-ldap/blob/master/lib/net/ldap.rb#L339

I meant to just write up a patch for this but it looks like it is much more involved that I originally thought. The IBM LDAP server, whatever it is, appears to support ControlType 2.16.840.1.113730.3.4.2 (RFC 3296).

When substituted with the hard-coded one in PagedResults, it works fine.

Happy to supply wireshark dumps, etc whatever to help out. Let me know.


Reply to this email directly or view it on GitHub:
#27

@strich
strich commented Jan 17, 2012

That is correct. If I use the default OID and I perform a search, the ldap server returns error code 50 - insufficient access rights. With the above OID it works fine.

@RoryO
RoryO commented Feb 29, 2012

I'm halfway leaning towards this is an IBM LDAP server bug since it shouldn't return 50 for invalid control type, but probably 2 (protocol error).

Still, there's lots of hack-ish stuff in here just to make old versions of MS LDAP work, but that's a necessity of pain because it's widely used.

I was going to suggest monkey-patching Net::LDAP::LDAPControls after you load the library but before you use it, but when I load the library, LDAPControls doesn't exist... but the namespace Net::LDAP::LdapControls does. That's a different matter that we'll have to figure out :\

@strich
strich commented Feb 29, 2012

Yeah not sure mate. I ended up forking the gem and just pointing my gemfile to the patched fork.

@Jamstah
Jamstah commented Apr 13, 2012

Searching was working on bluepages after I added the code to turn off paged searching if the server doesn't claim compatibility, which bluepages doesn't. Are you specifically enabling paged searching on your requests?

Feel free to get in touch - I've been cleared by IBM legal to contribute to this project, and am interested in maintaining bluepages compatibility.

From the RFC, that control isn't to do with Paged Searching, so the reason it solves the (as Rory says) incorrect return code) is that it basically doesn't ask for paging:

  1. The ManageDsaIT Control

The client may provide the ManageDsaIT control with an operation to
indicate that the operation is intended to manage objects within the
DSA (server) Information Tree. The control causes Directory-specific
entries (DSEs), regardless of type, to be treated as normal entries
allowing clients to interrogate and update these entries using LDAP
operations.

A client MAY specify the following control when issuing an add,
compare, delete, modify, modifyDN, search request or an extended
operation for which the control is defined.

The control type is 2.16.840.1.113730.3.4.2. The control criticality
may be TRUE or, if FALSE, absent. The control value is absent.

When the control is present in the request, the server SHALL NOT
generate a referral or continuation reference based upon information
held in referral objects and instead SHALL treat the referral object
as a normal entry. The server, however, is still free to return
referrals for other reasons. When not present, referral objects
SHALL be handled as described above.

The control MAY cause other objects to be treated as normal entries
as defined by subsequent documents.

@strich
strich commented Apr 16, 2012

Hi Jamstah,

No I wasn't specifically attempting to enable Paged Searching. Maybe its a default?

@Jamstah
Jamstah commented Apr 16, 2012

It used to be a default until I changed it to only send the control if the server reported it as supported.
https://github.com/ruby-ldap/ruby-net-ldap/blob/master/lib/net/ldap.rb#L1443

Unless you use the ignore_server_caps argument?
https://github.com/ruby-ldap/ruby-net-ldap/blob/master/lib/net/ldap.rb#L621

@strich
strich commented Apr 17, 2012

Hrm, when did you make the change? I branched my project and disabled LDAP auth so I could keep pushing forward, so I can't help debug/test further right now sadly. But the implementation was very simple. I might try to dig up the code I used this weekend for you.

@lpar
lpar commented Aug 21, 2012

It still doesn't work, I'm afraid. I have net-ldap-0.3.1 running against the IBM directory, I've checked that it has the .to_ber_sequence if paged_searches_supported line, but I still get the OpenStruct code=50, message="Insufficient Access Rights" error

@digglife

Oh...This issue is killing me these two days.I would never figure out why it doesn't work for Bluepage if I didn't reach here.Thanks strich,you are a life saver,literally.

@jch
Member
jch commented Oct 31, 2014

@digglife I'm not familiar with Bluepage, but would you be interested in submitting a pull request detailing your changes against the latest master? There are new maintainers on the project, and we'd love your help.

@digglife
digglife commented Nov 1, 2014

@jch It's been a while since I tweaked with v0.3.1. I didn't dig it too much back then. So I had a check with the latest code and wrote a piece of test script. It turns out that I can avoid this problem by setting force_no_page to true when I create the LDAP object. There is no need to change the module code.

@strich just replaces the OID for indicating paging ability of a LDAP Server with another irrelevant one, so the code used for handling paging doesn't work as it's supposed to do. I thinks it's the same as disabling it.

I tried dumping some data from the search function in connection.rb (https://github.com/ruby-ldap/ruby-net-ldap/blob/master/lib/net/ldap/connection.rb#L453), but I don't know if it helps...

looping ...
    controls: []
    message_id: 2
    result_pdu: <Net::LDAP::PDU:0x00000002a773b0 @message_id=2, @app_tag=5, @ldap_controls=[], @ldap_result={:resultCode=>0, :matchedDN=>"", :errorMessage=>""}>
looping ...
    controls: ["0$\x04\x161.2.840.113556.1.4.319\x01\x01\x00\x04\a0\x05\x02\x01~\x04\x00"]
    message_id: 2
    result_pdu: <Net::LDAP::PDU:0x00000002a82558 @message_id=2, @app_tag=5, @ldap_controls=[<OpenStruct oid="1.2.840.113556.1.4.319", criticality=false, value="0\x03\x02\x012\x04\x00">], @ldap_result={:resultCode=>50, :matchedDN=>"", :errorMessage=>""}>

Here is the supportedcontrol attribute of Bluepage.

   :supportedcontrol=>
    ["1.3.18.0.2.10.22",
     "2.16.840.1.113730.3.4.2",
     "1.3.18.0.2.10.5",
     "1.2.840.113556.1.4.473",
     "1.2.840.113556.1.4.319",
     "2.16.840.1.113730.3.4.3",
     "1.3.6.1.4.1.42.2.27.8.5.1",
     "1.2.840.113556.1.4.805",
     "1.3.18.0.2.10.21",
     "1.3.18.0.2.10.26",
     "1.3.18.0.2.10.25",
     "1.3.18.0.2.10.30",
     "1.3.18.0.2.10.32",
     "1.3.18.0.2.10.33",
     "1.3.18.0.2.10.23",
     "1.3.18.0.2.10.27",
     "1.3.18.0.2.10.24",
     "1.3.18.0.2.10.18",
     "1.3.18.0.2.10.15",
     "2.16.840.1.113730.3.4.18",
     "1.3.18.0.2.10.28"],
@jch
Member
jch commented Nov 1, 2014

@digglife great research! I think you're right that this would be fixed if paging wasn't enabled by default. #12 documents this as well. Would you be interesting in contributing a pull request to modify the default behavior to not page? I'd be happy to help code review or point to where you need to get started.

@digglife
digglife commented Nov 2, 2014

@jch The first thought crossed my mind is that changing DefaultForceNoPage to true... But wait, nobody would bother asking me for this kind of silly change. So maybe it's needed to re-organize the whole search function and some related blocks. I'm familiar with Perl so I can write some ruby script but I've never written serious production code with ruby before. So I'm excited that you invite me to involve in but I'm afraid that I'm not that qualified if you need a solid contributor. 😥

@frishrash

Had similar problem here. Resolution was to add :force_no_page => true argument to Net::LDAP.new as @digglife suggested. Both search and bind_as work, tested in v0.11.

If for any reason anyone is still interested in monkey patching as @RoryO suggested this code worked for me:

Net::LDAP::LDAPControls.class_eval {remove_const :PAGED_RESULTS} 
Net::LDAP::LDAPControls.const_set :PAGED_RESULTS, '2.16.840.1.113730.3.4.2'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment