ruby-ldap / ruby-net-ldap

Pure Ruby LDAP library
https://rubygems.org/gems/net-ldap
Other
399 stars 253 forks source link

Net::LDAP::DN - Retain trailing spaces in RDN values in DNs #412

Closed TomSellers closed 1 year ago

TomSellers commented 1 year ago

Net::LDAP::DN.each_pair and Net::LDAP::DN.to_a are stripping trailing spaces in the values they return. The comment for each_pair refers to RFC 2253 Section 3 for the rules on parsing the DN into key value pairs. It allows for spaces in values. In Section 2.4, which is just prior, it states how to escape leading and trailing spaces in values.

Net::LDAP::DN retains leading and trailing spaces and escapes as expected when calling to_s however when calling each_pair or to_a it is removing the trailing spaces.

For example: Original data: CN=Foo.bar.baz, OU=Foo \ ,OU=\ Bar, O=Baz to_s output: CN=Foo.bar.baz, OU=Foo \ ,OU=\ Bar, O=Baz to_a output:

CN: 'Foo.bar.baz'
OU: 'Foo'                <- This should be 'Foo    '
OU: '  Bar'
O: 'Baz'

This PR contains changes to change this behavior and tests to verify the results.

Before changes

irb
irb(main):001:0> require 'net/ldap'
=> true
irb(main):002:0> require 'net/ldap/dn'
=> true

# Check version
irb(main):003:0> Net::LDAP::VERSION
=> "0.17.1"

# create the object using the test string
irb(main):004:0> test = Net::LDAP::DN.new('CN=Foo.bar.baz, OU=Foo   \ ,OU=\  Bar, O=Baz')
=> #<Net::LDAP::DN:0x000000015bb4b138 @dn="CN=Foo.bar.baz, OU=Foo   \\ ,OU=\\  Bar, O=Baz">

# verify that the spaces exist and are escaped as expected in `to_s`
irb(main):005:0> test.to_s
=> "CN=Foo.bar.baz, OU=Foo   \\ ,OU=\\  Bar, O=Baz"

# verify that the values returned by `to_a` retain the spaces
# Failed - missing trailing spaces in `Foo    `
irb(main):007:0> test.to_a
=> ["CN", "Foo.bar.baz", "OU", "Foo", "OU", "  Bar", "O", "Baz"]

# verify that the values returned by each_pair retain the spaces
# Failed - missing trailing spaces in `Foo    `
irb(main):006:0> test.each_pair { |k, value| puts(k +": '" + value +"'") }
CN: 'Foo.bar.baz'
OU: 'Foo'
OU: '  Bar'
O: 'Baz'
=> nil

After changes

$ irb
irb(main):001:0> require 'net/ldap'
=> true
irb(main):002:0> require 'net/ldap/dn'
=> true

# create the object using the test string
irb(main):005:0> test = Net::LDAP::DN.new('CN=Foo.bar.baz, OU=Foo   \ ,OU=\  Bar, O=Baz')
=> #<Net::LDAP::DN:0x000000012fad3d58 @dn="CN=Foo.bar.baz, OU=Foo   \\ ,OU=\\  Bar, O=Baz">

# verify that the spaces exist and are escaped as expected in `to_s`
irb(main):006:0> test.to_s
=> "CN=Foo.bar.baz, OU=Foo   \\ ,OU=\\  Bar, O=Baz"

# verify that the values returned by `to_a` retain the spaces
irb(main):008:0> test.to_a
=> ["CN", "Foo.bar.baz", "OU", "Foo    ", "OU", "  Bar", "O", "Baz"]

# verify that the values returned by each_pair retain the spaces
irb(main):007:0> test.each_pair { |k, value| puts(k +": '" + value +"'") }
CN: 'Foo.bar.baz'
OU: 'Foo    '
OU: '  Bar'
O: 'Baz'
=> nil
TomSellers commented 1 year ago

Note, the jruby-9.2 test failure is due to that version of JRuby not being compatible with the version of bundler that is being used.

ERROR:  Error installing bundler:
    The last version of bundler (>= 0) to support your Ruby & RubyGems was 2.3.26. Try installing it with `gem install bundler -v 2.3.26`
    bundler requires Ruby version >= 2.6.0. The current ruby version is 2.5.8.0.
1
Error: Process completed with exit code 1.

JRuby 9.2.x is compatible with Ruby 2.5.x , while JRuby 9.3.x is compatible with Ruby 2.6.x.

TomSellers commented 1 year ago

@HarlemSquirrel Would it be possible to have this fix included in the next release?

HarlemSquirrel commented 1 year ago

@TomSellers Thanks for this. It looks great! Could you please update the branch from master so CI can run?

TomSellers commented 1 year ago

@HarlemSquirrel Triggered, the workflow is waiting on approval.