Using LDAP Controls in ruby-ldap

This is a bit of a stretch since it is as much about LDAP as it is
ruby but I'll ask it here anyway. I'd like to use the "paged results"
control/extension to LDAP for getting results sets larger than the
server allows. Has anyone used this or have any further pointers?

The gory details:

···

------------------------
ruby-ldap seems to have part of what is needed but I can't seem to tie
it together and get it to work. There is a LDAP::Control.new method
which appears to let me create a control (although a peek at the
source reveals a bug in the initialize script that prevents "oid" from
being initialized so I hack around it by assigning it after). The
search_ext function appears to happily accept this control object, but
the behavior is not as expected. Part of the problem might be that I
have no freakin clue what the second argument ( :value ) to
LDAP::Control.new should look like. What I have there is just based
on looking at RFC2696 which defines the paged results control for
LDAP. The RFC says this is BER encoded value but it looks like the
ldap-ruby code is doing that.

$ cat test.rb
#!/usr/bin/ruby

require 'ldap'
require 'pp'

control = LDAP::Control.new(nil, 'size=10', true)
control.oid="1.2.840.113556.1.4.319"

conn = LDAP::SSLConn.new('test-dc-02.xxxxx.com', 636, false)

conn.bind("test@xxxxxx.com", Password::get() )

conn.search_ext("ou=users,ou=test,dc=xxxxx,dc=com",
LDAP::LDAP_SCOPE_SUBTREE, "sn=*", ["sn"], false, serverctrls =
[control] ) { |r| pp r.attributes }

$ ./test.rb
Password:
./test.rb:16:in `search_ext': Critical extension is unavailable
(LDAP::ResultError)
        from ./test.rb:16

This looks like the extension - not the value - isn't supported.

According to the OpenLDAP list, AD used to be the only server that
supported this - maybe not anymore?

http://www.openldap.org/lists/openldap-devel/200207/msg00016.html

Anyway - I'd give it a go on an OpenLDAP 2.2 server if you have one
available and see what happens.

As to the value, it's unclear if the ruby lib will BER encode this for
you, Once I've move my install up to 2.2, I'll be able to test a
little more.

Poking around misc.c didn't make things clearer for me either.

You could try something like this
a = OpenSSL::ASN1::Sequence.new([OpenSSL::ASN1::Integer.new('10'),
OpenSSL::ASN1::OctetString.new('')])

control.value = a.to_der

I get conversion errors, but my openssl could be newer.

good luck,
will

ref: RFC 2696 - LDAP Control Extension for Simple Paged Results Manip (RFC2696)

···

On Thu, 4 Nov 2004 14:26:33 +0900, Jason Wold <jason.wold@gmail.com> wrote:

This is a bit of a stretch since it is as much about LDAP as it is
ruby but I'll ask it here anyway. I'd like to use the "paged results"
control/extension to LDAP for getting results sets larger than the
server allows. Has anyone used this or have any further pointers?

The gory details:
------------------------
ruby-ldap seems to have part of what is needed but I can't seem to tie
it together and get it to work. There is a LDAP::Control.new method
which appears to let me create a control (although a peek at the
source reveals a bug in the initialize script that prevents "oid" from
being initialized so I hack around it by assigning it after). The
search_ext function appears to happily accept this control object, but
the behavior is not as expected. Part of the problem might be that I
have no freakin clue what the second argument ( :value ) to
LDAP::Control.new should look like. What I have there is just based
on looking at RFC2696 which defines the paged results control for
LDAP. The RFC says this is BER encoded value but it looks like the
ldap-ruby code is doing that.

$ cat test.rb
#!/usr/bin/ruby

require 'ldap'
require 'pp'

control = LDAP::Control.new(nil, 'size=10', true)
control.oid="1.2.840.113556.1.4.319"

conn = LDAP::SSLConn.new('test-dc-02.xxxxx.com', 636, false)

conn.bind("test@xxxxxx.com", Password::get() )

conn.search_ext("ou=users,ou=test,dc=xxxxx,dc=com",
LDAP::LDAP_SCOPE_SUBTREE, "sn=*", ["sn"], false, serverctrls =
[control] ) { |r| pp r.attributes }

$ ./test.rb
Password:
./test.rb:16:in `search_ext': Critical extension is unavailable
(LDAP::ResultError)
        from ./test.rb:16

Thanks for the tip. Both AD and OpenLDAP 2.2 support this, although
OpenLDAP only supports it when using specific backends (bdb yes, ldbm
no)

Cheers,
Jason

···

On Fri, 5 Nov 2004 02:21:01 +0900, Will Drewry <drewry@gmail.com> wrote:

On Thu, 4 Nov 2004 14:26:33 +0900, Jason Wold <jason.wold@gmail.com> wrote:

> This is a bit of a stretch since it is as much about LDAP as it is
> ruby but I'll ask it here anyway. I'd like to use the "paged results"
> control/extension to LDAP for getting results sets larger than the
> server allows. Has anyone used this or have any further pointers?
>
> The gory details:
> ------------------------
> ruby-ldap seems to have part of what is needed but I can't seem to tie
> it together and get it to work. There is a LDAP::Control.new method
> which appears to let me create a control (although a peek at the
> source reveals a bug in the initialize script that prevents "oid" from
> being initialized so I hack around it by assigning it after). The
> search_ext function appears to happily accept this control object, but
> the behavior is not as expected. Part of the problem might be that I
> have no freakin clue what the second argument ( :value ) to
> LDAP::Control.new should look like. What I have there is just based
> on looking at RFC2696 which defines the paged results control for
> LDAP. The RFC says this is BER encoded value but it looks like the
> ldap-ruby code is doing that.
>
> $ cat test.rb
> #!/usr/bin/ruby
>
> require 'ldap'
> require 'pp'
>
> control = LDAP::Control.new(nil, 'size=10', true)
> control.oid="1.2.840.113556.1.4.319"
>
> conn = LDAP::SSLConn.new('test-dc-02.xxxxx.com', 636, false)
>
> conn.bind("test@xxxxxx.com", Password::get() )
>
> conn.search_ext("ou=users,ou=test,dc=xxxxx,dc=com",
> LDAP::LDAP_SCOPE_SUBTREE, "sn=*", ["sn"], false, serverctrls =
> [control] ) { |r| pp r.attributes }
>
> $ ./test.rb
> Password:
> ./test.rb:16:in `search_ext': Critical extension is unavailable
> (LDAP::ResultError)
> from ./test.rb:16
>
>

This looks like the extension - not the value - isn't supported.

According to the OpenLDAP list, AD used to be the only server that
supported this - maybe not anymore?

Re: simple paged results ( rfc2696 ) - has anyone look at this?

Anyway - I'd give it a go on an OpenLDAP 2.2 server if you have one
available and see what happens.

As to the value, it's unclear if the ruby lib will BER encode this for
you, Once I've move my install up to 2.2, I'll be able to test a
little more.

Poking around misc.c didn't make things clearer for me either.

You could try something like this
a = OpenSSL::ASN1::Sequence.new([OpenSSL::ASN1::Integer.new('10'),
OpenSSL::ASN1::OctetString.new('')])

control.value = a.to_der

I get conversion errors, but my openssl could be newer.

good luck,
will

ref: RFC 2696 - LDAP Control Extension for Simple Paged Results Manip (RFC2696)

'10' needs to be just the integer 10, and then it works.

···

On Fri, 5 Nov 2004 02:21:01 +0900, Will Drewry <drewry@gmail.com> wrote:

On Thu, 4 Nov 2004 14:26:33 +0900, Jason Wold <jason.wold@gmail.com> wrote:

You could try something like this
a = OpenSSL::ASN1::Sequence.new([OpenSSL::ASN1::Integer.new('10'),
OpenSSL::ASN1::OctetString.new('')])

control.value = a.to_der

I'd like to point out, for the record, that this is a perfect example of how
type checking in a language is a good thing.

Seriously, I'm not trying to restart that thread; I just want to draw the
attention of the anti-type-checking crowd to the OP.

···

On Friday 05 November 2004 20:30, Jason Wold wrote:

> You could try something like this
> a = OpenSSL::ASN1::Sequence.new([OpenSSL::ASN1::Integer.new('10'),
> OpenSSL::ASN1::OctetString.new('')])
>
> control.value = a.to_der

'10' needs to be just the integer 10, and then it works.

--
### SER
### Deutsch|Esperanto|Francaise|Linux|XML|Java|Ruby|Aikido
### http://www.germane-software.com/~ser jabber.com:ser ICQ:83578737
### GPG: http://www.germane-software.com/~ser/Security/ser_public.gpg

alternatively the source for OpenSSL::ASN1::Integer#initialize might/should
be written as

   def initialize arg
     arg = Integer arg
     ...
   end

and all would be well. i think a good general rule for production code is to

   a) convert to the type you need, String, Integer, etc.

   b) duck-type by checking for methods

but of course we never to that. i can say that, ultimately, i like the lack
of type checking in ruby since i find many methods (say using a tklabel with
the built-in logger class) just 'works' with the addition of a method or two.
it would be a shame to lose this flexiblity. i don't think strong typing is
all bad, but so many langauges get it wrong that the thought just makes me
cringe. the ocaml compiler sure is impressive tough. if i started out that
way i might be a strong typing fan but... i guess i think strong typing
without type inference is evil. i also hate getting 'int-ified' by c
compilers...

kind regards.

-a

···

On Sun, 7 Nov 2004, Sean E. Russell wrote:

--nextPart1581570.dOv9ppeehb
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

On Friday 05 November 2004 20:30, Jason Wold wrote:

You could try something like this
a =3D OpenSSL::ASN1::Sequence.new([OpenSSL::ASN1::Integer.new('10'),
OpenSSL::ASN1::OctetString.new('')])

control.value =3D a.to_der

'10' needs to be just the integer 10, and then it works.

I'd like to point out, for the record, that this is a perfect example of ho=
w=20
type checking in a language is a good thing.

--

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
When you do something, you should burn yourself completely, like a good
bonfire, leaving no trace of yourself. --Shunryu Suzuki

===============================================================================