net-ldap 0.16.0 → 0.17.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 (73) hide show
  1. checksums.yaml +5 -5
  2. data/History.rdoc +47 -0
  3. data/README.rdoc +18 -6
  4. data/lib/net/ber/core_ext.rb +6 -6
  5. data/lib/net/ber.rb +2 -2
  6. data/lib/net/ldap/auth_adapter/gss_spnego.rb +2 -2
  7. data/lib/net/ldap/auth_adapter/sasl.rb +1 -1
  8. data/lib/net/ldap/auth_adapter/simple.rb +1 -1
  9. data/lib/net/ldap/connection.rb +14 -10
  10. data/lib/net/ldap/dataset.rb +3 -3
  11. data/lib/net/ldap/dn.rb +10 -10
  12. data/lib/net/ldap/entry.rb +13 -2
  13. data/lib/net/ldap/error.rb +2 -26
  14. data/lib/net/ldap/filter.rb +10 -3
  15. data/lib/net/ldap/instrumentation.rb +2 -2
  16. data/lib/net/ldap/password.rb +7 -5
  17. data/lib/net/ldap/pdu.rb +1 -1
  18. data/lib/net/ldap/version.rb +1 -1
  19. data/lib/net/ldap.rb +39 -16
  20. data/lib/net/snmp.rb +1 -1
  21. data/lib/net-ldap.rb +1 -1
  22. metadata +19 -109
  23. data/.gitignore +0 -9
  24. data/.rubocop.yml +0 -20
  25. data/.rubocop_todo.yml +0 -753
  26. data/.travis.yml +0 -33
  27. data/CONTRIBUTING.md +0 -54
  28. data/Gemfile +0 -2
  29. data/Rakefile +0 -23
  30. data/net-ldap.gemspec +0 -37
  31. data/script/changelog +0 -47
  32. data/script/generate-fixture-ca +0 -48
  33. data/script/install-openldap +0 -134
  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/ca/ca.info +0 -4
  40. data/test/fixtures/ca/cacert.pem +0 -24
  41. data/test/fixtures/ca/cakey.pem +0 -190
  42. data/test/fixtures/openldap/memberof.ldif +0 -33
  43. data/test/fixtures/openldap/retcode.ldif +0 -76
  44. data/test/fixtures/openldap/slapd.conf.ldif +0 -67
  45. data/test/fixtures/seed.ldif +0 -374
  46. data/test/integration/test_add.rb +0 -28
  47. data/test/integration/test_ber.rb +0 -30
  48. data/test/integration/test_bind.rb +0 -244
  49. data/test/integration/test_delete.rb +0 -31
  50. data/test/integration/test_open.rb +0 -88
  51. data/test/integration/test_password_modify.rb +0 -80
  52. data/test/integration/test_return_codes.rb +0 -38
  53. data/test/integration/test_search.rb +0 -77
  54. data/test/support/vm/openldap/.gitignore +0 -1
  55. data/test/support/vm/openldap/README.md +0 -64
  56. data/test/support/vm/openldap/Vagrantfile +0 -34
  57. data/test/test_auth_adapter.rb +0 -15
  58. data/test/test_dn.rb +0 -44
  59. data/test/test_entry.rb +0 -65
  60. data/test/test_filter.rb +0 -223
  61. data/test/test_filter_parser.rb +0 -24
  62. data/test/test_helper.rb +0 -74
  63. data/test/test_ldap.rb +0 -114
  64. data/test/test_ldap_connection.rb +0 -491
  65. data/test/test_ldif.rb +0 -104
  66. data/test/test_password.rb +0 -10
  67. data/test/test_rename.rb +0 -77
  68. data/test/test_search.rb +0 -39
  69. data/test/test_snmp.rb +0 -119
  70. data/test/test_ssl_ber.rb +0 -40
  71. data/test/testdata.ldif +0 -101
  72. data/testserver/ldapserver.rb +0 -209
  73. data/testserver/testdata.ldif +0 -101
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d4f923e6ac7f10fc49fff6cfc20271a5eb318360
4
- data.tar.gz: 1967da0f521b403b511ad50760baa18fa9cc6dd5
2
+ SHA256:
3
+ metadata.gz: 02707fcb56d13184b4bbcc16c1555a0d417efb7e20c216a97ee8f28c9553ea84
4
+ data.tar.gz: 26a82f5021146fe6ec84d83e41722364964e155eb898102e3a8618facc020d9a
5
5
  SHA512:
6
- metadata.gz: '09bbb19ba3dba954202b1cb94aad491eb64e30a9582cc2c99e2b7ee6cc4cb79da7117bf2cbfc33a0ec851913fe15e76ef91534f92cc87cfe973e28fb1d8c03e1'
7
- data.tar.gz: d01aab8d40574cbe7ea738dd0698b092072894ac5c1af9238a9f527651f16dc786e787234d80af116b547137b033fd8966c9c9dc7a48b93c9646f8a274dec677
6
+ metadata.gz: d19e1bc7cdcaceff6263f2bca2e9326ef441e301ab74556c42313e01704800abb59231f760abec64a8f2d1e313c18324b97c57a64d2b2ee24943be9e4bd2c428
7
+ data.tar.gz: fa69d36265e7b11b7c83cf812caca680e30af3a0be31c145d70396835081fc06f6a2bf43262ec08f4d6fab1094823dc70de069441229a991f3c5b2eadeb7c4e5
data/History.rdoc CHANGED
@@ -1,3 +1,50 @@
1
+ === Net::LDAP 0.17.0
2
+ * Added private recursive_delete as alternative to DELETE_TREE #268
3
+ * Test suite updates #373 #376 #377
4
+ * Use Base64.strict_encode64 and SSHA256 #303
5
+ * Remove deprecated ConnectionRefusedError #366
6
+ * Added method to get a duplicate of the internal Hash #286
7
+ * remove a circular require #380
8
+ * fix LdapServerAsnSyntax compile #379
9
+ * Implement '==' operator for entries #381
10
+ * fix for undefined method for write exception #383
11
+
12
+ === Net::LDAP 0.16.3
13
+
14
+ * Add Net::LDAP::InvalidDNError #371
15
+ * Use require_relative instead of require #360
16
+ * Address some warnings and fix JRuby test omissions #365
17
+ * Bump rake dev dependency to 12.3 #359
18
+ * Enable rubocop in ci #251
19
+ * Enhance rubocop configuration and test syntax #344
20
+ * CI: Drop rbx-2, uninstallable #364
21
+ * Fix RuboCop warnings #312
22
+ * Fix wrong error class #305
23
+ * CONTRIBUTING.md: Repair link to Issues #309
24
+ * Make the generate() method more idiomatic... #326
25
+ * Make encode_sort_controls() more idiomatic... #327
26
+ * Make the instrument() method more idiomatic... #328
27
+ * Fix uninitialised Net::LDAP::LdapPduError #338
28
+ * README.rdoc: Use SVG build badge #310
29
+ * Update TravisCI config to inclue Ruby 2.7 #346
30
+ * add explicit ** to silence Ruby 2.7 warning #342
31
+ * Support parsing filters with attribute tags #345
32
+ * Bump rubocop development dependency version #336
33
+ * Add link to generated and hosted documentation on rubydoc #319
34
+ * Fix 'uninitialized constant Net::LDAP::PDU::LdapPduError' error #317
35
+ * simplify encoding logic: no more chomping required #362
36
+
37
+ === Net::LDAP 0.16.2
38
+
39
+ * Net::LDAP#open does not cache bind result {#334}[https://github.com/ruby-ldap/ruby-net-ldap/pull/334]
40
+ * Fix CI build {#333}[https://github.com/ruby-ldap/ruby-net-ldap/pull/333]
41
+ * Fix to "undefined method 'result_code'" {#308}[https://github.com/ruby-ldap/ruby-net-ldap/pull/308]
42
+ * Fixed Exception: incompatible character encodings: ASCII-8BIT and UTF-8 in filter.rb {#285}[https://github.com/ruby-ldap/ruby-net-ldap/pull/285]
43
+
44
+ === Net::LDAP 0.16.1
45
+
46
+ * Send DN and newPassword with password_modify request {#271}[https://github.com/ruby-ldap/ruby-net-ldap/pull/271]
47
+
1
48
  === Net::LDAP 0.16.0
2
49
 
3
50
  * Sasl fix {#281}[https://github.com/ruby-ldap/ruby-net-ldap/pull/281]
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/gems/net-ldap/Net/LDAP] for documentation and usage samples.
25
27
 
26
28
  == Requirements
27
29
 
@@ -53,16 +55,26 @@ This task will run the test suite and the
53
55
  rake rubotest
54
56
 
55
57
  CI takes too long? If your local box supports
56
- {Vagrant}[https://www.vagrantup.com/], you can run most of the tests
57
- in a VM on your local box. For more details and setup instructions, see
58
- {test/support/vm/openldap/README.md}[https://github.com/ruby-ldap/ruby-net-ldap/tree/master/test/support/vm/openldap/README.md]
58
+ {Docker}[https://www.docker.com/], you can also run integration tests locally.
59
+ Simply run:
60
+
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
59
71
 
60
72
  == Release
61
73
 
62
74
  This section is for gem maintainers to cut a new version of the gem.
63
75
 
64
76
  * Check out a new branch `release-VERSION`
65
- * 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/].
66
78
  * Update `History.rdoc`. Get latest changes with `script/changelog`
67
79
  * Open a pull request with these changes for review
68
80
  * After merging, on the master branch, run `script/release`
@@ -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
  ##
@@ -349,4 +349,4 @@ module Net::BER
349
349
  Null = Net::BER::BerIdentifiedNull.new
350
350
  end
351
351
 
352
- 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,4 +1,4 @@
1
- require 'net/ldap/auth_adapter'
1
+ require_relative '../auth_adapter'
2
2
 
3
3
  module Net
4
4
  class LDAP
@@ -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
@@ -181,7 +181,7 @@ class Net::LDAP::Connection #:nodoc:
181
181
  # have to call it, but perhaps it will come in handy someday.
182
182
  #++
183
183
  def close
184
- return if @conn.nil?
184
+ return if !defined?(@conn) || @conn.nil?
185
185
  @conn.close
186
186
  @conn = nil
187
187
  end
@@ -300,7 +300,7 @@ class Net::LDAP::Connection #:nodoc:
300
300
  control[2] = (control[2] == true).to_ber
301
301
  control.to_ber_sequence
302
302
  end
303
- sort_control = [
303
+ [
304
304
  Net::LDAP::LDAPControls::SORT_REQUEST.to_ber,
305
305
  false.to_ber,
306
306
  sort_control_values.to_ber_sequence.to_s.to_ber,
@@ -467,6 +467,10 @@ class Net::LDAP::Connection #:nodoc:
467
467
  end
468
468
  end
469
469
 
470
+ if result_pdu.nil?
471
+ raise Net::LDAP::ResponseMissingOrInvalidError, "response missing"
472
+ end
473
+
470
474
  # count number of pages of results
471
475
  payload[:page_count] ||= 0
472
476
  payload[:page_count] += 1
@@ -592,11 +596,11 @@ class Net::LDAP::Connection #:nodoc:
592
596
 
593
597
  ext_seq = [Net::LDAP::PasswdModifyOid.to_ber_contextspecific(0)]
594
598
 
595
- unless args[:old_password].nil?
596
- pwd_seq = [args[:old_password].to_ber(0x81)]
597
- pwd_seq << args[:new_password].to_ber(0x82) unless args[:new_password].nil?
598
- ext_seq << pwd_seq.to_ber_sequence.to_ber(0x81)
599
- end
599
+ pwd_seq = []
600
+ pwd_seq << dn.to_ber(0x80)
601
+ pwd_seq << args[:old_password].to_ber(0x81) unless args[:old_password].nil?
602
+ pwd_seq << args[:new_password].to_ber(0x82) unless args[:new_password].nil?
603
+ ext_seq << pwd_seq.to_ber_sequence.to_ber(0x81)
600
604
 
601
605
  request = ext_seq.to_ber_appsequence(Net::LDAP::PDU::ExtendedRequest)
602
606
 
@@ -606,7 +610,7 @@ class Net::LDAP::Connection #:nodoc:
606
610
  pdu = queued_read(message_id)
607
611
 
608
612
  if !pdu || pdu.app_tag != Net::LDAP::PDU::ExtendedResponse
609
- raise Net::LDAP::ResponseMissingError, "response missing or invalid"
613
+ raise Net::LDAP::ResponseMissingOrInvalidError, "response missing or invalid"
610
614
  end
611
615
 
612
616
  pdu
@@ -686,7 +690,7 @@ class Net::LDAP::Connection #:nodoc:
686
690
  #
687
691
  # Typically a TCPSocket, but can be a OpenSSL::SSL::SSLSocket
688
692
  def socket
689
- return @conn if defined? @conn
693
+ return @conn if defined?(@conn) && !@conn.nil?
690
694
 
691
695
  # First refactoring uses the existing methods open_connection and
692
696
  # prepare_socket to set @conn. Next cleanup would centralize connection
@@ -706,7 +710,7 @@ class Net::LDAP::Connection #:nodoc:
706
710
  # Wrap around Socket.tcp to normalize with other Socket initializers
707
711
  class DefaultSocket
708
712
  def self.new(host, port, socket_opts = {})
709
- Socket.tcp(host, port, socket_opts)
713
+ Socket.tcp(host, port, **socket_opts)
710
714
  end
711
715
  end
712
716
  end # class Connection
@@ -1,3 +1,5 @@
1
+ require_relative 'entry'
2
+
1
3
  # -*- ruby encoding: utf-8 -*-
2
4
  ##
3
5
  # An LDAP Dataset. Used primarily as an intermediate format for converting
@@ -103,7 +105,7 @@ class Net::LDAP::Dataset < Hash
103
105
  # with the conversion of
104
106
  def from_entry(entry)
105
107
  dataset = Net::LDAP::Dataset.new
106
- hash = { }
108
+ hash = {}
107
109
  entry.each_attribute do |attribute, value|
108
110
  next if attribute == :dn
109
111
  hash[attribute] = value
@@ -164,5 +166,3 @@ class Net::LDAP::Dataset < Hash
164
166
  end
165
167
  end
166
168
  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
@@ -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
@@ -145,14 +145,14 @@ class Net::LDAP::DN
145
145
  yield key.string.strip, value.string.rstrip
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
@@ -162,14 +162,14 @@ class Net::LDAP::DN
162
162
  yield key.string.strip, value.string.rstrip
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
- raise "DN badly formed" unless
172
+ raise Net::LDAP::InvalidDNError, "DN badly formed" unless
173
173
  [:value, :value_normal, :value_hexstring, :value_end].include? state
174
174
 
175
175
  yield key.string.strip, value.string.rstrip
@@ -1,3 +1,5 @@
1
+ require_relative 'dataset'
2
+
1
3
  # -*- ruby encoding: utf-8 -*-
2
4
  ##
3
5
  # Objects of this class represent individual entries in an LDAP directory.
@@ -133,6 +135,13 @@ class Net::LDAP::Entry
133
135
  @myhash.keys
134
136
  end
135
137
 
138
+ ##
139
+ # Creates a duplicate of the internal Hash containing the attributes
140
+ # of the entry.
141
+ def to_h
142
+ @myhash.dup
143
+ end
144
+
136
145
  ##
137
146
  # Accesses each of the attributes present in the Entry.
138
147
  #
@@ -187,6 +196,8 @@ class Net::LDAP::Entry
187
196
  sym.to_s[-1] == ?=
188
197
  end
189
198
  private :setter?
190
- end # class Entry
191
199
 
192
- require 'net/ldap/dataset' unless defined? Net::LDAP::Dataset
200
+ def ==(other)
201
+ other.instance_of?(self.class) && @myhash == other.to_h
202
+ end
203
+ end # class Entry
@@ -1,38 +1,13 @@
1
1
  class Net::LDAP
2
- class LdapError < StandardError
3
- def message
4
- "Deprecation warning: Net::LDAP::LdapError is no longer used. Use Net::LDAP::Error or rescue one of it's subclasses. \n" + super
5
- end
6
- end
7
-
8
2
  class Error < StandardError; end
9
3
 
10
4
  class AlreadyOpenedError < Error; end
11
5
  class SocketError < Error; end
12
- class ConnectionRefusedError < Error;
13
- def initialize(*args)
14
- warn_deprecation_message
15
- super
16
- end
17
-
18
- def message
19
- warn_deprecation_message
20
- super
21
- end
22
-
23
- private
24
-
25
- def warn_deprecation_message
26
- warn "Deprecation warning: Net::LDAP::ConnectionRefused will be deprecated. Use Errno::ECONNREFUSED instead."
27
- end
28
- end
29
6
  class ConnectionError < Error
30
7
  def self.new(errors)
31
8
  error = errors.first.first
32
9
  if errors.size == 1
33
- if error.kind_of? Errno::ECONNREFUSED
34
- return Net::LDAP::ConnectionRefusedError.new(error.message)
35
- end
10
+ return error if error.is_a? Errno::ECONNREFUSED
36
11
 
37
12
  return Net::LDAP::Error.new(error.message)
38
13
  end
@@ -60,6 +35,7 @@ class Net::LDAP
60
35
  class ResponseTypeInvalidError < Error; end
61
36
  class ResponseMissingOrInvalidError < Error; end
62
37
  class EmptyDNError < Error; end
38
+ class InvalidDNError < Error; end
63
39
  class HashTypeUnsupportedError < Error; end
64
40
  class OperatorError < Error; end
65
41
  class SubstringFilterError < Error; end
@@ -490,7 +490,7 @@ class Net::LDAP::Filter
490
490
  when :eq
491
491
  if @right == "*" # presence test
492
492
  @left.to_s.to_ber_contextspecific(7)
493
- elsif @right =~ /[*]/ # substring
493
+ elsif @right.to_s =~ /[*]/ # substring
494
494
  # Parsing substrings is a little tricky. We use String#split to
495
495
  # break a string into substrings delimited by the * (star)
496
496
  # character. But we also need to know whether there is a star at the
@@ -645,8 +645,15 @@ class Net::LDAP::Filter
645
645
 
646
646
  ##
647
647
  # Converts escaped characters (e.g., "\\28") to unescaped characters
648
+ # @note slawson20170317: Don't attempt to unescape 16 byte binary data which we assume are objectGUIDs
649
+ # The binary form of 5936AE79-664F-44EA-BCCB-5C39399514C6 triggers a BINARY -> UTF-8 conversion error
648
650
  def unescape(right)
649
- right.to_s.gsub(/\\([a-fA-F\d]{2})/) { [$1.hex].pack("U") }
651
+ right = right.to_s
652
+ if right.length == 16 && right.encoding == Encoding::BINARY
653
+ right
654
+ else
655
+ right.to_s.gsub(/\\([a-fA-F\d]{2})/) { [$1.hex].pack("U") }
656
+ end
650
657
  end
651
658
  private :unescape
652
659
 
@@ -748,7 +755,7 @@ class Net::LDAP::Filter
748
755
  # This parses a given expression inside of parentheses.
749
756
  def parse_filter_branch(scanner)
750
757
  scanner.scan(/\s*/)
751
- if token = scanner.scan(/[-\w:.]*[\w]/)
758
+ if token = scanner.scan(/[-\w:.;]*[\w]/)
752
759
  scanner.scan(/\s*/)
753
760
  if op = scanner.scan(/<=|>=|!=|:=|=/)
754
761
  scanner.scan(/\s*/)
@@ -12,8 +12,8 @@ module Net::LDAP::Instrumentation
12
12
  def instrument(event, payload = {})
13
13
  payload = (payload || {}).dup
14
14
  if instrumentation_service
15
- instrumentation_service.instrument(event, payload) do |payload|
16
- payload[:result] = yield(payload) if block_given?
15
+ instrumentation_service.instrument(event, payload) do |instr_payload|
16
+ instr_payload[:result] = yield(instr_payload) if block_given?
17
17
  end
18
18
  else
19
19
  yield(payload) if block_given?
@@ -1,5 +1,6 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
2
  require 'digest/sha1'
3
+ require 'digest/sha2'
3
4
  require 'digest/md5'
4
5
  require 'base64'
5
6
  require 'securerandom'
@@ -19,20 +20,21 @@ class Net::LDAP::Password
19
20
  # * Should we provide sha1 as a synonym for sha1? I vote no because then
20
21
  # should you also provide ssha1 for symmetry?
21
22
  #
22
- attribute_value = ""
23
23
  def generate(type, str)
24
24
  case type
25
25
  when :md5
26
- attribute_value = '{MD5}' + Base64.encode64(Digest::MD5.digest(str)).chomp!
26
+ '{MD5}' + Base64.strict_encode64(Digest::MD5.digest(str))
27
27
  when :sha
28
- attribute_value = '{SHA}' + Base64.encode64(Digest::SHA1.digest(str)).chomp!
28
+ '{SHA}' + Base64.strict_encode64(Digest::SHA1.digest(str))
29
29
  when :ssha
30
30
  salt = SecureRandom.random_bytes(16)
31
- attribute_value = '{SSHA}' + Base64.encode64(Digest::SHA1.digest(str + salt) + salt).chomp!
31
+ '{SSHA}' + Base64.strict_encode64(Digest::SHA1.digest(str + salt) + salt)
32
+ when :ssha256
33
+ salt = SecureRandom.random_bytes(16)
34
+ '{SSHA256}' + Base64.strict_encode64(Digest::SHA256.digest(str + salt) + salt)
32
35
  else
33
36
  raise Net::LDAP::HashTypeUnsupportedError, "Unsupported password-hash type (#{type})"
34
37
  end
35
- return attribute_value
36
38
  end
37
39
  end
38
40
  end
data/lib/net/ldap/pdu.rb CHANGED
@@ -123,7 +123,7 @@ class Net::LDAP::PDU
123
123
  when ExtendedResponse
124
124
  parse_extended_response(ber_object[1])
125
125
  else
126
- raise LdapPduError.new("unknown pdu-type: #{@app_tag}")
126
+ raise Error.new("unknown pdu-type: #{@app_tag}")
127
127
  end
128
128
 
129
129
  parse_controls(ber_object[2]) if ber_object[2]
@@ -1,5 +1,5 @@
1
1
  module Net
2
2
  class LDAP
3
- VERSION = "0.16.0"
3
+ VERSION = "0.17.0"
4
4
  end
5
5
  end
data/lib/net/ldap.rb CHANGED
@@ -17,19 +17,19 @@ module Net # :nodoc:
17
17
  end
18
18
  require 'socket'
19
19
 
20
- require 'net/ber'
21
- require 'net/ldap/pdu'
22
- require 'net/ldap/filter'
23
- require 'net/ldap/dataset'
24
- require 'net/ldap/password'
25
- require 'net/ldap/entry'
26
- require 'net/ldap/instrumentation'
27
- require 'net/ldap/connection'
28
- require 'net/ldap/version'
29
- require 'net/ldap/error'
30
- require 'net/ldap/auth_adapter'
31
- require 'net/ldap/auth_adapter/simple'
32
- require 'net/ldap/auth_adapter/sasl'
20
+ require_relative 'ber'
21
+ require_relative 'ldap/pdu'
22
+ require_relative 'ldap/filter'
23
+ require_relative 'ldap/dataset'
24
+ require_relative 'ldap/password'
25
+ require_relative 'ldap/entry'
26
+ require_relative 'ldap/instrumentation'
27
+ require_relative 'ldap/connection'
28
+ require_relative 'ldap/version'
29
+ require_relative 'ldap/error'
30
+ require_relative 'ldap/auth_adapter'
31
+ require_relative 'ldap/auth_adapter/simple'
32
+ require_relative 'ldap/auth_adapter/sasl'
33
33
 
34
34
  Net::LDAP::AuthAdapter.register([:simple, :anon, :anonymous], Net::LDAP::AuthAdapter::Simple)
35
35
  Net::LDAP::AuthAdapter.register(:sasl, Net::LDAP::AuthAdapter::Sasl)
@@ -712,7 +712,7 @@ class Net::LDAP
712
712
  begin
713
713
  @open_connection = new_connection
714
714
  payload[:connection] = @open_connection
715
- payload[:bind] = @open_connection.bind(@auth)
715
+ payload[:bind] = @result = @open_connection.bind(@auth)
716
716
  yield self
717
717
  ensure
718
718
  @open_connection.close if @open_connection
@@ -1182,14 +1182,22 @@ class Net::LDAP
1182
1182
  # entries. This method sends an extra control code to tell the LDAP server
1183
1183
  # to do a tree delete. ('1.2.840.113556.1.4.805')
1184
1184
  #
1185
+ # If the LDAP server does not support the DELETE_TREE control code, subordinate
1186
+ # entries are deleted recursively instead.
1187
+ #
1185
1188
  # Returns True or False to indicate whether the delete succeeded. Extended
1186
1189
  # status information is available by calling #get_operation_result.
1187
1190
  #
1188
1191
  # dn = "mail=deleteme@example.com, ou=people, dc=example, dc=com"
1189
1192
  # ldap.delete_tree :dn => dn
1190
1193
  def delete_tree(args)
1191
- delete(args.merge(:control_codes => [[Net::LDAP::LDAPControls::DELETE_TREE, true]]))
1194
+ if search_root_dse[:supportedcontrol].include? Net::LDAP::LDAPControls::DELETE_TREE
1195
+ delete(args.merge(:control_codes => [[Net::LDAP::LDAPControls::DELETE_TREE, true]]))
1196
+ else
1197
+ recursive_delete(args)
1198
+ end
1192
1199
  end
1200
+
1193
1201
  # This method is experimental and subject to change. Return the rootDSE
1194
1202
  # record from the LDAP server as a Net::LDAP::Entry, or an empty Entry if
1195
1203
  # the server doesn't return the record.
@@ -1320,7 +1328,7 @@ class Net::LDAP
1320
1328
  # Force connect to see if there's a connection error
1321
1329
  connection.socket
1322
1330
  connection
1323
- rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT, Net::LDAP::ConnectionRefusedError => e
1331
+ rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT => e
1324
1332
  @result = {
1325
1333
  :resultCode => 52,
1326
1334
  :errorMessage => ResultStrings[ResultCodeUnavailable],
@@ -1340,4 +1348,19 @@ class Net::LDAP
1340
1348
  end
1341
1349
  end
1342
1350
 
1351
+ # Recursively delete a dn and it's subordinate children.
1352
+ # This is useful when a server does not support the DELETE_TREE control code.
1353
+ def recursive_delete(args)
1354
+ raise EmptyDNError unless args.is_a?(Hash) && args.key?(:dn)
1355
+ # Delete Children
1356
+ search(base: args[:dn], scope: Net::LDAP::SearchScope_SingleLevel) do |entry|
1357
+ recursive_delete(dn: entry.dn)
1358
+ end
1359
+ # Delete Self
1360
+ unless delete(dn: args[:dn])
1361
+ raise Net::LDAP::Error, get_operation_result[:error_message].to_s
1362
+ end
1363
+ true
1364
+ end
1365
+
1343
1366
  end # class LDAP
data/lib/net/snmp.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
  # :stopdoc:
5
5
  module Net
data/lib/net-ldap.rb CHANGED
@@ -1,2 +1,2 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
- require 'net/ldap'
2
+ require_relative 'net/ldap'