net-ldap 0.15.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +5 -5
  2. data/History.rdoc +76 -0
  3. data/README.rdoc +18 -8
  4. data/lib/net/ber/ber_parser.rb +3 -3
  5. data/lib/net/ber/core_ext.rb +6 -6
  6. data/lib/net/ber.rb +5 -6
  7. data/lib/net/ldap/auth_adapter/gss_spnego.rb +2 -2
  8. data/lib/net/ldap/auth_adapter/sasl.rb +4 -2
  9. data/lib/net/ldap/auth_adapter/simple.rb +1 -1
  10. data/lib/net/ldap/connection.rb +57 -46
  11. data/lib/net/ldap/dataset.rb +1 -3
  12. data/lib/net/ldap/dn.rb +21 -30
  13. data/lib/net/ldap/entry.rb +15 -7
  14. data/lib/net/ldap/error.rb +2 -26
  15. data/lib/net/ldap/filter.rb +10 -3
  16. data/lib/net/ldap/instrumentation.rb +2 -2
  17. data/lib/net/ldap/password.rb +7 -5
  18. data/lib/net/ldap/pdu.rb +1 -1
  19. data/lib/net/ldap/version.rb +1 -1
  20. data/lib/net/ldap.rb +93 -58
  21. data/lib/net/snmp.rb +1 -1
  22. data/lib/net-ldap.rb +1 -1
  23. metadata +16 -101
  24. data/.gitignore +0 -9
  25. data/.rubocop.yml +0 -17
  26. data/.rubocop_todo.yml +0 -599
  27. data/.travis.yml +0 -33
  28. data/CONTRIBUTING.md +0 -54
  29. data/Gemfile +0 -2
  30. data/Rakefile +0 -23
  31. data/net-ldap.gemspec +0 -37
  32. data/script/changelog +0 -47
  33. data/script/install-openldap +0 -115
  34. data/script/package +0 -7
  35. data/script/release +0 -16
  36. data/test/ber/core_ext/test_array.rb +0 -22
  37. data/test/ber/core_ext/test_string.rb +0 -25
  38. data/test/ber/test_ber.rb +0 -153
  39. data/test/fixtures/cacert.pem +0 -20
  40. data/test/fixtures/openldap/memberof.ldif +0 -33
  41. data/test/fixtures/openldap/retcode.ldif +0 -76
  42. data/test/fixtures/openldap/slapd.conf.ldif +0 -67
  43. data/test/fixtures/seed.ldif +0 -374
  44. data/test/integration/test_add.rb +0 -28
  45. data/test/integration/test_ber.rb +0 -30
  46. data/test/integration/test_bind.rb +0 -42
  47. data/test/integration/test_delete.rb +0 -31
  48. data/test/integration/test_open.rb +0 -88
  49. data/test/integration/test_password_modify.rb +0 -80
  50. data/test/integration/test_return_codes.rb +0 -38
  51. data/test/integration/test_search.rb +0 -77
  52. data/test/support/vm/openldap/.gitignore +0 -1
  53. data/test/support/vm/openldap/README.md +0 -32
  54. data/test/support/vm/openldap/Vagrantfile +0 -33
  55. data/test/test_auth_adapter.rb +0 -15
  56. data/test/test_dn.rb +0 -44
  57. data/test/test_entry.rb +0 -65
  58. data/test/test_filter.rb +0 -223
  59. data/test/test_filter_parser.rb +0 -24
  60. data/test/test_helper.rb +0 -66
  61. data/test/test_ldap.rb +0 -114
  62. data/test/test_ldap_connection.rb +0 -493
  63. data/test/test_ldif.rb +0 -104
  64. data/test/test_password.rb +0 -10
  65. data/test/test_rename.rb +0 -77
  66. data/test/test_search.rb +0 -39
  67. data/test/test_snmp.rb +0 -119
  68. data/test/test_ssl_ber.rb +0 -40
  69. data/test/testdata.ldif +0 -101
  70. data/testserver/ldapserver.rb +0 -209
  71. data/testserver/testdata.ldif +0 -101
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 26f8c374bc1cc4a9c355ae968cf1ca29d1efc335
4
- data.tar.gz: 2bd1fc2b1ef9bd5939200a06ba9ce4bf24ae85de
2
+ SHA256:
3
+ metadata.gz: 1fdcc1a3fefe3fb2bf1dbb91ec9e00734252fdda634ae0e2344b9dd6e6b86cd2
4
+ data.tar.gz: 8526bd506b632e74193c80119280fd4b333731b1e3d75791427a12e62cab775a
5
5
  SHA512:
6
- metadata.gz: 8d7caa7c7800648300d1cfb52dc09d54dd7df4eb39f2ed88e9f8fcdf8cb8119a4e6582541dfe4ebcca69739cd7166366621a2f76dd974fd7f370796a7c4fe14c
7
- data.tar.gz: 71856da21d5c8387cc25f9364d27c43cc48300bd7dd7213b6b35f5a3de42509479d9682f51bc8d894ddd36c21ff5cc0c04e034b051f376b4ab9f17518a249581
6
+ metadata.gz: e2f9e53240eeedd964463c6bc719cc86e57e5a66c5a769371e16d97005f9b63933797f33384e0192b6e128cc4fec1de46e3cca2886fce963439d86b4b3c0665f
7
+ data.tar.gz: e4af635dce612600ba48a110ebae1d3c30c00f9c5adcfeba1b6eca1d4d760646674d399cac256f96490bcad6d884146cb891ac14d57f8734556ed7e331baac90
data/History.rdoc CHANGED
@@ -1,3 +1,79 @@
1
+ === Net::LDAP 0.19.0
2
+ * Net::LDAP::DN - Retain trailing spaces in RDN values in DNs #412
3
+ * Add in ability for users to specify LDAP controls when conducting searches #411
4
+ * Document connect_timeout in Constructor Details #415
5
+ * Fix openssl error when using multiple hosts #417
6
+
7
+ === Net::LDAP 0.18.0
8
+ * Fix escaping of # and space in attrs #408
9
+ * Add support to use SNI #406
10
+ * Drop Ruby 2.5 and JRuby 9.2 from CI tests
11
+ * Bump rubocop to 1.48.1
12
+ * Update CI for TruffleRuby 22
13
+
14
+ === Net::LDAP 0.17.1
15
+ * Fixed shebang of bash #385
16
+ * Omit some tests for now until we update our CA cert #386
17
+ * Add Ruby 3.0 support #388
18
+ * Add TruffleRuby 21.0.0 to CI #389
19
+ * Correct a typo in an error message #391
20
+ * Enable bundler caching for travis #390
21
+ * Fix circular require while loading lib/net/ldap/entry.rb and lib/net/ldap/dataset.rb #392
22
+ * Handle nil value in GetbyteForSSLSocket::getbyte #306
23
+
24
+ === Net::LDAP 0.17.0
25
+ * Added private recursive_delete as alternative to DELETE_TREE #268
26
+ * Test suite updates #373 #376 #377
27
+ * Use Base64.strict_encode64 and SSHA256 #303
28
+ * Remove deprecated ConnectionRefusedError #366
29
+ * Added method to get a duplicate of the internal Hash #286
30
+ * remove a circular require #380
31
+ * fix LdapServerAsnSyntax compile #379
32
+ * Implement '==' operator for entries #381
33
+ * fix for undefined method for write exception #383
34
+
35
+ === Net::LDAP 0.16.3
36
+
37
+ * Add Net::LDAP::InvalidDNError #371
38
+ * Use require_relative instead of require #360
39
+ * Address some warnings and fix JRuby test omissions #365
40
+ * Bump rake dev dependency to 12.3 #359
41
+ * Enable rubocop in ci #251
42
+ * Enhance rubocop configuration and test syntax #344
43
+ * CI: Drop rbx-2, uninstallable #364
44
+ * Fix RuboCop warnings #312
45
+ * Fix wrong error class #305
46
+ * CONTRIBUTING.md: Repair link to Issues #309
47
+ * Make the generate() method more idiomatic... #326
48
+ * Make encode_sort_controls() more idiomatic... #327
49
+ * Make the instrument() method more idiomatic... #328
50
+ * Fix uninitialised Net::LDAP::LdapPduError #338
51
+ * README.rdoc: Use SVG build badge #310
52
+ * Update TravisCI config to inclue Ruby 2.7 #346
53
+ * add explicit ** to silence Ruby 2.7 warning #342
54
+ * Support parsing filters with attribute tags #345
55
+ * Bump rubocop development dependency version #336
56
+ * Add link to generated and hosted documentation on rubydoc #319
57
+ * Fix 'uninitialized constant Net::LDAP::PDU::LdapPduError' error #317
58
+ * simplify encoding logic: no more chomping required #362
59
+
60
+ === Net::LDAP 0.16.2
61
+
62
+ * Net::LDAP#open does not cache bind result {#334}[https://github.com/ruby-ldap/ruby-net-ldap/pull/334]
63
+ * Fix CI build {#333}[https://github.com/ruby-ldap/ruby-net-ldap/pull/333]
64
+ * Fix to "undefined method 'result_code'" {#308}[https://github.com/ruby-ldap/ruby-net-ldap/pull/308]
65
+ * Fixed Exception: incompatible character encodings: ASCII-8BIT and UTF-8 in filter.rb {#285}[https://github.com/ruby-ldap/ruby-net-ldap/pull/285]
66
+
67
+ === Net::LDAP 0.16.1
68
+
69
+ * Send DN and newPassword with password_modify request {#271}[https://github.com/ruby-ldap/ruby-net-ldap/pull/271]
70
+
71
+ === Net::LDAP 0.16.0
72
+
73
+ * Sasl fix {#281}[https://github.com/ruby-ldap/ruby-net-ldap/pull/281]
74
+ * enable TLS hostname validation {#279}[https://github.com/ruby-ldap/ruby-net-ldap/pull/279]
75
+ * update rubocop to 0.42.0 {#278}[https://github.com/ruby-ldap/ruby-net-ldap/pull/278]
76
+
1
77
  === Net::LDAP 0.15.0
2
78
 
3
79
  * Respect connect_timeout when establishing SSL connections {#273}[https://github.com/ruby-ldap/ruby-net-ldap/pull/273]
data/README.rdoc CHANGED
@@ -1,4 +1,6 @@
1
- = Net::LDAP for Ruby {<img src="https://travis-ci.org/ruby-ldap/ruby-net-ldap.png" />}[https://travis-ci.org/ruby-ldap/ruby-net-ldap]
1
+ = Net::LDAP for Ruby
2
+ {<img src="https://badge.fury.io/rb/net-ldap.svg" alt="Gem Version" />}[https://badge.fury.io/rb/net-ldap]
3
+ {<img src="https://travis-ci.org/ruby-ldap/ruby-net-ldap.svg" />}[https://travis-ci.org/ruby-ldap/ruby-net-ldap]
2
4
 
3
5
  == Description
4
6
 
@@ -21,7 +23,7 @@ the most recent LDAP RFCs (4510–4519, plus portions of 4520–4532).
21
23
 
22
24
  == Synopsis
23
25
 
24
- See Net::LDAP for documentation and usage samples.
26
+ See {Net::LDAP on rubydoc.info}[https://www.rubydoc.info/github/ruby-ldap/ruby-net-ldap] for documentation and usage samples.
25
27
 
26
28
  == Requirements
27
29
 
@@ -52,19 +54,27 @@ This task will run the test suite and the
52
54
 
53
55
  rake rubotest
54
56
 
55
- To run the integration tests against an LDAP server:
57
+ CI takes too long? If your local box supports
58
+ {Docker}[https://www.docker.com/], you can also run integration tests locally.
59
+ Simply run:
56
60
 
57
- cd test/support/vm/openldap
58
- vagrant up
59
- cd ../../../..
60
- INTEGRATION=openldap bundle exec rake rubotest
61
+ script/ldap-docker
62
+ INTEGRATION=openldap rake test
63
+
64
+ Or, use {Docker Compose}[https://docs.docker.com/compose/]. See docker-compose.yml for available Ruby versions.
65
+
66
+ docker-compose run ci-2.7
67
+
68
+ CAVEAT: you need to add the following line to /etc/hosts
69
+ 127.0.0.1 ldap.example.org
70
+ 127.0.0.1 cert.mismatch.example.org
61
71
 
62
72
  == Release
63
73
 
64
74
  This section is for gem maintainers to cut a new version of the gem.
65
75
 
66
76
  * Check out a new branch `release-VERSION`
67
- * Update lib/net/ldap/version.rb to next version number X.X.X following {semver}(http://semver.org/).
77
+ * Update lib/net/ldap/version.rb to next version number X.X.X following {semver}[http://semver.org/].
68
78
  * Update `History.rdoc`. Get latest changes with `script/changelog`
69
79
  * Open a pull request with these changes for review
70
80
  * After merging, on the master branch, run `script/release`
@@ -172,10 +172,10 @@ module Net::BER::BERParser
172
172
  yield id, content_length if block_given?
173
173
 
174
174
  if -1 == content_length
175
- raise Net::BER::BerError, "Indeterminite BER content length not implemented."
176
- else
177
- data = read(content_length)
175
+ raise Net::BER::BerError,
176
+ "Indeterminite BER content length not implemented."
178
177
  end
178
+ data = read(content_length)
179
179
 
180
180
  parse_ber_object(syntax, id, data)
181
181
  end
@@ -1,5 +1,5 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
- require 'net/ber/ber_parser'
2
+ require_relative 'ber_parser'
3
3
  # :stopdoc:
4
4
  class IO
5
5
  include Net::BER::BERParser
@@ -19,35 +19,35 @@ end
19
19
  module Net::BER::Extensions # :nodoc:
20
20
  end
21
21
 
22
- require 'net/ber/core_ext/string'
22
+ require_relative 'core_ext/string'
23
23
  # :stopdoc:
24
24
  class String
25
25
  include Net::BER::BERParser
26
26
  include Net::BER::Extensions::String
27
27
  end
28
28
 
29
- require 'net/ber/core_ext/array'
29
+ require_relative 'core_ext/array'
30
30
  # :stopdoc:
31
31
  class Array
32
32
  include Net::BER::Extensions::Array
33
33
  end
34
34
  # :startdoc:
35
35
 
36
- require 'net/ber/core_ext/integer'
36
+ require_relative 'core_ext/integer'
37
37
  # :stopdoc:
38
38
  class Integer
39
39
  include Net::BER::Extensions::Integer
40
40
  end
41
41
  # :startdoc:
42
42
 
43
- require 'net/ber/core_ext/true_class'
43
+ require_relative 'core_ext/true_class'
44
44
  # :stopdoc:
45
45
  class TrueClass
46
46
  include Net::BER::Extensions::TrueClass
47
47
  end
48
48
  # :startdoc:
49
49
 
50
- require 'net/ber/core_ext/false_class'
50
+ require_relative 'core_ext/false_class'
51
51
  # :stopdoc:
52
52
  class FalseClass
53
53
  include Net::BER::Extensions::FalseClass
data/lib/net/ber.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
- require 'net/ldap/version'
2
+ require_relative 'ldap/version'
3
3
 
4
4
  module Net # :nodoc:
5
5
  ##
@@ -327,11 +327,10 @@ class Net::BER::BerIdentifiedString < String
327
327
  # Check the encoding of the newly created String and set the encoding
328
328
  # to 'UTF-8' (NOTE: we do NOT change the bytes, but only set the
329
329
  # encoding to 'UTF-8').
330
+ return unless encoding == Encoding::BINARY
330
331
  current_encoding = encoding
331
- if current_encoding == Encoding::BINARY
332
- force_encoding('UTF-8')
333
- force_encoding(current_encoding) unless valid_encoding?
334
- end
332
+ force_encoding('UTF-8')
333
+ force_encoding(current_encoding) unless valid_encoding?
335
334
  end
336
335
  end
337
336
 
@@ -350,4 +349,4 @@ module Net::BER
350
349
  Null = Net::BER::BerIdentifiedNull.new
351
350
  end
352
351
 
353
- require 'net/ber/core_ext'
352
+ require_relative 'ber/core_ext'
@@ -1,5 +1,5 @@
1
- require 'net/ldap/auth_adapter'
2
- require 'net/ldap/auth_adapter/sasl'
1
+ require_relative '../auth_adapter'
2
+ require_relative 'sasl'
3
3
 
4
4
  module Net
5
5
  class LDAP
@@ -1,9 +1,11 @@
1
- require 'net/ldap/auth_adapter'
1
+ require_relative '../auth_adapter'
2
2
 
3
3
  module Net
4
4
  class LDAP
5
5
  class AuthAdapter
6
6
  class Sasl < Net::LDAP::AuthAdapter
7
+ MAX_SASL_CHALLENGES = 10
8
+
7
9
  #--
8
10
  # Required parameters: :mechanism, :initial_credential and
9
11
  # :challenge_response
@@ -47,7 +49,7 @@ module Net
47
49
  end
48
50
 
49
51
  return pdu unless pdu.result_code == Net::LDAP::ResultCodeSaslBindInProgress
50
- raise Net::LDAP::SASLChallengeOverflowError, "sasl-challenge overflow" if ((n += 1) > MaxSaslChallenges)
52
+ raise Net::LDAP::SASLChallengeOverflowError, "sasl-challenge overflow" if ((n += 1) > MAX_SASL_CHALLENGES)
51
53
 
52
54
  cred = chall.call(pdu.result_server_sasl_creds)
53
55
  end
@@ -1,4 +1,4 @@
1
- require 'net/ldap/auth_adapter'
1
+ require_relative '../auth_adapter'
2
2
 
3
3
  module Net
4
4
  class LDAP
@@ -7,7 +7,6 @@ class Net::LDAP::Connection #:nodoc:
7
7
  DefaultConnectTimeout = 5
8
8
 
9
9
  LdapVersion = 3
10
- MaxSaslChallenges = 10
11
10
 
12
11
  # Initialize a connection to an LDAP server
13
12
  #
@@ -31,12 +30,12 @@ class Net::LDAP::Connection #:nodoc:
31
30
  @socket_class = socket_class
32
31
  end
33
32
 
34
- def prepare_socket(server, timeout=nil)
33
+ def prepare_socket(server, timeout=nil, hostname='127.0.0.1')
35
34
  socket = server[:socket]
36
35
  encryption = server[:encryption]
37
36
 
38
37
  @conn = socket
39
- setup_encryption(encryption, timeout) if encryption
38
+ setup_encryption(encryption, timeout, hostname) if encryption
40
39
  end
41
40
 
42
41
  def open_connection(server)
@@ -51,7 +50,16 @@ class Net::LDAP::Connection #:nodoc:
51
50
  errors = []
52
51
  hosts.each do |host, port|
53
52
  begin
54
- prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)), timeout)
53
+ prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)), timeout, host)
54
+ if encryption
55
+ if encryption[:tls_options] &&
56
+ encryption[:tls_options][:verify_mode] &&
57
+ encryption[:tls_options][:verify_mode] == OpenSSL::SSL::VERIFY_NONE
58
+ warn "not verifying SSL hostname of LDAPS server '#{host}:#{port}'"
59
+ else
60
+ @conn.post_connection_check(host)
61
+ end
62
+ end
55
63
  return
56
64
  rescue Net::LDAP::Error, SocketError, SystemCallError,
57
65
  OpenSSL::SSL::SSLError => e
@@ -66,7 +74,8 @@ class Net::LDAP::Connection #:nodoc:
66
74
 
67
75
  module GetbyteForSSLSocket
68
76
  def getbyte
69
- getc.ord
77
+ c = getc
78
+ c && c.ord
70
79
  end
71
80
  end
72
81
 
@@ -77,7 +86,7 @@ class Net::LDAP::Connection #:nodoc:
77
86
  end
78
87
  end
79
88
 
80
- def self.wrap_with_ssl(io, tls_options = {}, timeout=nil)
89
+ def self.wrap_with_ssl(io, tls_options = {}, timeout=nil, hostname=nil)
81
90
  raise Net::LDAP::NoOpenSSLError, "OpenSSL is unavailable" unless Net::LDAP::HasOpenSSL
82
91
 
83
92
  ctx = OpenSSL::SSL::SSLContext.new
@@ -87,6 +96,7 @@ class Net::LDAP::Connection #:nodoc:
87
96
  ctx.set_params(tls_options) unless tls_options.empty?
88
97
 
89
98
  conn = OpenSSL::SSL::SSLSocket.new(io, ctx)
99
+ conn.hostname = hostname
90
100
 
91
101
  begin
92
102
  if timeout
@@ -95,17 +105,13 @@ class Net::LDAP::Connection #:nodoc:
95
105
  conn.connect
96
106
  end
97
107
  rescue IO::WaitReadable
98
- if IO.select([conn], nil, nil, timeout)
99
- retry
100
- else
101
- raise Errno::ETIMEDOUT, "OpenSSL connection read timeout"
102
- end
108
+ raise Errno::ETIMEDOUT, "OpenSSL connection read timeout" unless
109
+ IO.select([conn], nil, nil, timeout)
110
+ retry
103
111
  rescue IO::WaitWritable
104
- if IO.select(nil, [conn], nil, timeout)
105
- retry
106
- else
107
- raise Errno::ETIMEDOUT, "OpenSSL connection write timeout"
108
- end
112
+ raise Errno::ETIMEDOUT, "OpenSSL connection write timeout" unless
113
+ IO.select(nil, [conn], nil, timeout)
114
+ retry
109
115
  end
110
116
 
111
117
  # Doesn't work:
@@ -143,11 +149,11 @@ class Net::LDAP::Connection #:nodoc:
143
149
  # communications, as with simple_tls. Thanks for Kouhei Sutou for
144
150
  # generously contributing the :start_tls path.
145
151
  #++
146
- def setup_encryption(args, timeout=nil)
152
+ def setup_encryption(args, timeout=nil, hostname=nil)
147
153
  args[:tls_options] ||= {}
148
154
  case args[:method]
149
155
  when :simple_tls
150
- @conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout)
156
+ @conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout, hostname)
151
157
  # additional branches requiring server validation and peer certs, etc.
152
158
  # go here.
153
159
  when :start_tls
@@ -163,11 +169,9 @@ class Net::LDAP::Connection #:nodoc:
163
169
  raise Net::LDAP::NoStartTLSResultError, "no start_tls result"
164
170
  end
165
171
 
166
- if pdu.result_code.zero?
167
- @conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout)
168
- else
169
- raise Net::LDAP::StartTLSError, "start_tls failed: #{pdu.result_code}"
170
- end
172
+ raise Net::LDAP::StartTLSError,
173
+ "start_tls failed: #{pdu.result_code}" unless pdu.result_code.zero?
174
+ @conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout, hostname)
171
175
  else
172
176
  raise Net::LDAP::EncMethodUnsupportedError, "unsupported encryption method #{args[:method]}"
173
177
  end
@@ -179,7 +183,7 @@ class Net::LDAP::Connection #:nodoc:
179
183
  # have to call it, but perhaps it will come in handy someday.
180
184
  #++
181
185
  def close
182
- return if @conn.nil?
186
+ return if !defined?(@conn) || @conn.nil?
183
187
  @conn.close
184
188
  @conn = nil
185
189
  end
@@ -197,12 +201,10 @@ class Net::LDAP::Connection #:nodoc:
197
201
 
198
202
  # read messages until we have a match for the given message_id
199
203
  while pdu = read
200
- if pdu.message_id == message_id
201
- return pdu
202
- else
203
- message_queue[pdu.message_id].push pdu
204
- next
205
- end
204
+ return pdu if pdu.message_id == message_id
205
+
206
+ message_queue[pdu.message_id].push pdu
207
+ next
206
208
  end
207
209
 
208
210
  pdu
@@ -300,7 +302,7 @@ class Net::LDAP::Connection #:nodoc:
300
302
  control[2] = (control[2] == true).to_ber
301
303
  control.to_ber_sequence
302
304
  end
303
- sort_control = [
305
+ [
304
306
  Net::LDAP::LDAPControls::SORT_REQUEST.to_ber,
305
307
  false.to_ber,
306
308
  sort_control_values.to_ber_sequence.to_s.to_ber,
@@ -400,12 +402,11 @@ class Net::LDAP::Connection #:nodoc:
400
402
  # should collect this into a private helper to clarify the structure
401
403
  query_limit = 0
402
404
  if size > 0
403
- if paged
404
- query_limit = (((size - n_results) < 126) ? (size -
405
- n_results) : 0)
406
- else
407
- query_limit = size
408
- end
405
+ query_limit = if paged
406
+ (((size - n_results) < 126) ? (size - n_results) : 0)
407
+ else
408
+ size
409
+ end
409
410
  end
410
411
 
411
412
  request = [
@@ -423,6 +424,7 @@ class Net::LDAP::Connection #:nodoc:
423
424
  # this breaks when calling to_ber. (Can't force binary data to UTF-8)
424
425
  # we have to disable paging (even though server supports it) to get around this...
425
426
 
427
+ user_controls = args.fetch(:controls, [])
426
428
  controls = []
427
429
  controls <<
428
430
  [
@@ -432,7 +434,12 @@ class Net::LDAP::Connection #:nodoc:
432
434
  rfc2696_cookie.map(&:to_ber).to_ber_sequence.to_s.to_ber,
433
435
  ].to_ber_sequence if paged
434
436
  controls << ber_sort if ber_sort
435
- controls = controls.empty? ? nil : controls.to_ber_contextspecific(0)
437
+ if controls.empty? && user_controls.empty?
438
+ controls = nil
439
+ else
440
+ controls += user_controls
441
+ controls = controls.to_ber_contextspecific(0)
442
+ end
436
443
 
437
444
  write(request, controls, message_id)
438
445
 
@@ -468,6 +475,10 @@ class Net::LDAP::Connection #:nodoc:
468
475
  end
469
476
  end
470
477
 
478
+ if result_pdu.nil?
479
+ raise Net::LDAP::ResponseMissingOrInvalidError, "response missing"
480
+ end
481
+
471
482
  # count number of pages of results
472
483
  payload[:page_count] ||= 0
473
484
  payload[:page_count] += 1
@@ -593,11 +604,11 @@ class Net::LDAP::Connection #:nodoc:
593
604
 
594
605
  ext_seq = [Net::LDAP::PasswdModifyOid.to_ber_contextspecific(0)]
595
606
 
596
- unless args[:old_password].nil?
597
- pwd_seq = [args[:old_password].to_ber(0x81)]
598
- pwd_seq << args[:new_password].to_ber(0x82) unless args[:new_password].nil?
599
- ext_seq << pwd_seq.to_ber_sequence.to_ber(0x81)
600
- end
607
+ pwd_seq = []
608
+ pwd_seq << dn.to_ber(0x80)
609
+ pwd_seq << args[:old_password].to_ber(0x81) unless args[:old_password].nil?
610
+ pwd_seq << args[:new_password].to_ber(0x82) unless args[:new_password].nil?
611
+ ext_seq << pwd_seq.to_ber_sequence.to_ber(0x81)
601
612
 
602
613
  request = ext_seq.to_ber_appsequence(Net::LDAP::PDU::ExtendedRequest)
603
614
 
@@ -607,7 +618,7 @@ class Net::LDAP::Connection #:nodoc:
607
618
  pdu = queued_read(message_id)
608
619
 
609
620
  if !pdu || pdu.app_tag != Net::LDAP::PDU::ExtendedResponse
610
- raise Net::LDAP::ResponseMissingError, "response missing or invalid"
621
+ raise Net::LDAP::ResponseMissingOrInvalidError, "response missing or invalid"
611
622
  end
612
623
 
613
624
  pdu
@@ -687,7 +698,7 @@ class Net::LDAP::Connection #:nodoc:
687
698
  #
688
699
  # Typically a TCPSocket, but can be a OpenSSL::SSL::SSLSocket
689
700
  def socket
690
- return @conn if defined? @conn
701
+ return @conn if defined?(@conn) && !@conn.nil?
691
702
 
692
703
  # First refactoring uses the existing methods open_connection and
693
704
  # prepare_socket to set @conn. Next cleanup would centralize connection
@@ -707,7 +718,7 @@ class Net::LDAP::Connection #:nodoc:
707
718
  # Wrap around Socket.tcp to normalize with other Socket initializers
708
719
  class DefaultSocket
709
720
  def self.new(host, port, socket_opts = {})
710
- Socket.tcp(host, port, socket_opts)
721
+ Socket.tcp(host, port, **socket_opts)
711
722
  end
712
723
  end
713
724
  end # class Connection
@@ -103,7 +103,7 @@ class Net::LDAP::Dataset < Hash
103
103
  # with the conversion of
104
104
  def from_entry(entry)
105
105
  dataset = Net::LDAP::Dataset.new
106
- hash = { }
106
+ hash = {}
107
107
  entry.each_attribute do |attribute, value|
108
108
  next if attribute == :dn
109
109
  hash[attribute] = value
@@ -164,5 +164,3 @@ class Net::LDAP::Dataset < Hash
164
164
  end
165
165
  end
166
166
  end
167
-
168
- require 'net/ldap/entry' unless defined? Net::LDAP::Entry
data/lib/net/ldap/dn.rb CHANGED
@@ -57,19 +57,19 @@ class Net::LDAP::DN
57
57
  state = :key_oid
58
58
  key << char
59
59
  when ' ' then state = :key
60
- else raise "DN badly formed"
60
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
61
61
  end
62
62
  when :key_normal then
63
63
  case char
64
64
  when '=' then state = :value
65
65
  when 'a'..'z', 'A'..'Z', '0'..'9', '-', ' ' then key << char
66
- else raise "DN badly formed"
66
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
67
67
  end
68
68
  when :key_oid then
69
69
  case char
70
70
  when '=' then state = :value
71
71
  when '0'..'9', '.', ' ' then key << char
72
- else raise "DN badly formed"
72
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
73
73
  end
74
74
  when :value then
75
75
  case char
@@ -81,7 +81,7 @@ class Net::LDAP::DN
81
81
  value << char
82
82
  when ',' then
83
83
  state = :key
84
- yield key.string.strip, value.string.rstrip
84
+ yield key.string.strip, value.string
85
85
  key = StringIO.new
86
86
  value = StringIO.new;
87
87
  else
@@ -93,7 +93,7 @@ class Net::LDAP::DN
93
93
  when '\\' then state = :value_normal_escape
94
94
  when ',' then
95
95
  state = :key
96
- yield key.string.strip, value.string.rstrip
96
+ yield key.string.strip, value.string
97
97
  key = StringIO.new
98
98
  value = StringIO.new;
99
99
  else value << char
@@ -110,7 +110,7 @@ class Net::LDAP::DN
110
110
  when '0'..'9', 'a'..'f', 'A'..'F' then
111
111
  state = :value_normal
112
112
  value << "#{hex_buffer}#{char}".to_i(16).chr
113
- else raise "DN badly formed"
113
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
114
114
  end
115
115
  when :value_quoted then
116
116
  case char
@@ -132,7 +132,7 @@ class Net::LDAP::DN
132
132
  when '0'..'9', 'a'..'f', 'A'..'F' then
133
133
  state = :value_quoted
134
134
  value << "#{hex_buffer}#{char}".to_i(16).chr
135
- else raise "DN badly formed"
135
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
136
136
  end
137
137
  when :value_hexstring then
138
138
  case char
@@ -142,38 +142,37 @@ class Net::LDAP::DN
142
142
  when ' ' then state = :value_end
143
143
  when ',' then
144
144
  state = :key
145
- yield key.string.strip, value.string.rstrip
145
+ yield key.string.strip, value.string
146
146
  key = StringIO.new
147
147
  value = StringIO.new;
148
- else raise "DN badly formed"
148
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
149
149
  end
150
150
  when :value_hexstring_hex then
151
151
  case char
152
152
  when '0'..'9', 'a'..'f', 'A'..'F' then
153
153
  state = :value_hexstring
154
154
  value << char
155
- else raise "DN badly formed"
155
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
156
156
  end
157
157
  when :value_end then
158
158
  case char
159
159
  when ' ' then state = :value_end
160
160
  when ',' then
161
161
  state = :key
162
- yield key.string.strip, value.string.rstrip
162
+ yield key.string.strip, value.string
163
163
  key = StringIO.new
164
164
  value = StringIO.new;
165
- else raise "DN badly formed"
165
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
166
166
  end
167
- else raise "Fell out of state machine"
167
+ else raise Net::LDAP::InvalidDNError, "Fell out of state machine"
168
168
  end
169
169
  end
170
170
 
171
171
  # Last pair
172
- if [:value, :value_normal, :value_hexstring, :value_end].include? state
173
- yield key.string.strip, value.string.rstrip
174
- else
175
- raise "DN badly formed"
176
- end
172
+ raise Net::LDAP::InvalidDNError, "DN badly formed" unless
173
+ [:value, :value_normal, :value_hexstring, :value_end].include? state
174
+
175
+ yield key.string.strip, value.string
177
176
  end
178
177
 
179
178
  ##
@@ -193,27 +192,19 @@ class Net::LDAP::DN
193
192
  # http://tools.ietf.org/html/rfc2253 section 2.4 lists these exceptions
194
193
  # for dn values. All of the following must be escaped in any normal string
195
194
  # using a single backslash ('\') as escape.
196
- ESCAPES = {
197
- ',' => ',',
198
- '+' => '+',
199
- '"' => '"',
200
- '\\' => '\\',
201
- '<' => '<',
202
- '>' => '>',
203
- ';' => ';',
204
- }
195
+ ESCAPES = %w[, + " \\ < > ;]
205
196
 
206
- # Compiled character class regexp using the keys from the above hash, and
197
+ # Compiled character class regexp using the values from the above list, and
207
198
  # checking for a space or # at the start, or space at the end, of the
208
199
  # string.
209
200
  ESCAPE_RE = Regexp.new("(^ |^#| $|[" +
210
- ESCAPES.keys.map { |e| Regexp.escape(e) }.join +
201
+ ESCAPES.map { |e| Regexp.escape(e) }.join +
211
202
  "])")
212
203
 
213
204
  ##
214
205
  # Escape a string for use in a DN value
215
206
  def self.escape(string)
216
- string.gsub(ESCAPE_RE) { |char| "\\" + ESCAPES[char] }
207
+ string.gsub(ESCAPE_RE) { |char| "\\" + char }
217
208
  end
218
209
 
219
210
  ##