ruby-net-ldap icon indicating copy to clipboard operation
ruby-net-ldap copied to clipboard

LDAP PagedResults ControlType Incompatible

Open strich opened this issue 13 years ago • 16 comments

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.

strich avatar Jan 17 '12 03:01 strich

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: https://github.com/ruby-ldap/ruby-net-ldap/issues/27

garbagecat avatar Jan 17 '12 14:01 garbagecat

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.

strich avatar Jan 17 '12 21:01 strich

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 :\

RoryO avatar Feb 29 '12 05:02 RoryO

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

strich avatar Feb 29 '12 06:02 strich

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.

Jamstah avatar Apr 13 '12 14:04 Jamstah

Hi Jamstah,

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

strich avatar Apr 16 '12 01:04 strich

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

Jamstah avatar Apr 16 '12 09:04 Jamstah

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.

strich avatar Apr 17 '12 03:04 strich

It seems to be there in your branch: https://github.com/strich/ruby-net-ldap/blob/master/lib/net/ldap.rb#L1398

Jamstah avatar Apr 17 '12 12:04 Jamstah

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

lpar avatar Aug 21 '12 15:08 lpar

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.

digglife avatar Jan 14 '14 08:01 digglife

@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.

jch avatar Oct 31 '14 20:10 jch

@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"],

digglife avatar Nov 01 '14 15:11 digglife

@digglife :sparkles: great research! I think you're right that this would be fixed if paging wasn't enabled by default. https://github.com/ruby-ldap/ruby-net-ldap/issues/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.

jch avatar Nov 01 '14 15:11 jch

@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. :disappointed_relieved:

digglife avatar Nov 02 '14 13:11 digglife

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'

frishrash avatar Jun 02 '15 05:06 frishrash