net-ldap 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of net-ldap might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop.yml +12 -0
- data/.rubocop_todo.yml +282 -145
- data/Contributors.rdoc +1 -0
- data/History.rdoc +17 -0
- data/README.rdoc +1 -1
- data/lib/net/ber.rb +3 -2
- data/lib/net/ber/ber_parser.rb +1 -1
- data/lib/net/ber/core_ext/array.rb +1 -1
- data/lib/net/ber/core_ext/integer.rb +1 -1
- data/lib/net/ber/core_ext/string.rb +1 -1
- data/lib/net/ldap.rb +89 -24
- data/lib/net/ldap/auth_adapter/gss_spnego.rb +2 -2
- data/lib/net/ldap/auth_adapter/sasl.rb +2 -2
- data/lib/net/ldap/connection.rb +108 -25
- data/lib/net/ldap/dataset.rb +2 -2
- data/lib/net/ldap/entry.rb +3 -3
- data/lib/net/ldap/filter.rb +5 -5
- data/lib/net/ldap/pdu.rb +26 -2
- data/lib/net/ldap/version.rb +1 -1
- data/lib/net/snmp.rb +18 -18
- data/test/ber/core_ext/test_array.rb +1 -1
- data/test/ber/test_ber.rb +2 -2
- data/test/fixtures/openldap/slapd.conf.ldif +1 -1
- data/test/integration/test_add.rb +1 -1
- data/test/integration/test_ber.rb +1 -1
- data/test/integration/test_delete.rb +1 -1
- data/test/integration/test_open.rb +1 -1
- data/test/integration/test_password_modify.rb +80 -0
- data/test/integration/test_search.rb +1 -1
- data/test/test_auth_adapter.rb +6 -3
- data/test/test_dn.rb +3 -3
- data/test/test_filter.rb +4 -4
- data/test/test_ldap.rb +51 -10
- data/test/test_ldap_connection.rb +62 -51
- data/test/test_ldif.rb +10 -10
- data/test/test_search.rb +2 -2
- data/test/test_snmp.rb +4 -4
- data/testserver/ldapserver.rb +11 -12
- metadata +5 -4
data/lib/net/ldap/dataset.rb
CHANGED
@@ -29,7 +29,7 @@ class Net::LDAP::Dataset < Hash
|
|
29
29
|
keys.sort.each do |dn|
|
30
30
|
ary << "dn: #{dn}"
|
31
31
|
|
32
|
-
attributes = self[dn].keys.map
|
32
|
+
attributes = self[dn].keys.map(&:to_s).sort
|
33
33
|
attributes.each do |attr|
|
34
34
|
self[dn][attr.to_sym].each do |value|
|
35
35
|
if attr == "userpassword" or value_is_binary?(value)
|
@@ -141,7 +141,7 @@ class Net::LDAP::Dataset < Hash
|
|
141
141
|
# $' is the dn-value
|
142
142
|
# Avoid the Base64 class because not all Ruby versions have it.
|
143
143
|
dn = ($1 == ":") ? $'.unpack('m').shift : $'
|
144
|
-
ds[dn] = Hash.new { |k,v| k[v] = [] }
|
144
|
+
ds[dn] = Hash.new { |k, v| k[v] = [] }
|
145
145
|
yield :dn, dn if block_given?
|
146
146
|
elsif line.empty?
|
147
147
|
dn = nil
|
data/lib/net/ldap/entry.rb
CHANGED
@@ -141,10 +141,10 @@ class Net::LDAP::Entry
|
|
141
141
|
# (possibly empty) \Array of data values.
|
142
142
|
def each # :yields: attribute-name, data-values-array
|
143
143
|
if block_given?
|
144
|
-
attribute_names.each
|
145
|
-
attr_name,values = a,self[a]
|
144
|
+
attribute_names.each do|a|
|
145
|
+
attr_name, values = a, self[a]
|
146
146
|
yield attr_name, values
|
147
|
-
|
147
|
+
end
|
148
148
|
end
|
149
149
|
end
|
150
150
|
alias_method :each_attribute, :each
|
data/lib/net/ldap/filter.rb
CHANGED
@@ -23,7 +23,7 @@
|
|
23
23
|
class Net::LDAP::Filter
|
24
24
|
##
|
25
25
|
# Known filter types.
|
26
|
-
FilterTypes = [
|
26
|
+
FilterTypes = [:ne, :eq, :ge, :le, :and, :or, :not, :ex, :bineq]
|
27
27
|
|
28
28
|
def initialize(op, left, right) #:nodoc:
|
29
29
|
unless FilterTypes.include?(op)
|
@@ -287,7 +287,7 @@ class Net::LDAP::Filter
|
|
287
287
|
when 0xa4 # context-specific constructed 4, "substring"
|
288
288
|
str = ""
|
289
289
|
final = false
|
290
|
-
ber.last.each
|
290
|
+
ber.last.each do |b|
|
291
291
|
case b.ber_identifier
|
292
292
|
when 0x80 # context-specific primitive 0, SubstringFilter "initial"
|
293
293
|
raise Net::LDAP::SubstringFilterError, "Unrecognized substring filter; bad initial value." if str.length > 0
|
@@ -298,7 +298,7 @@ class Net::LDAP::Filter
|
|
298
298
|
str += "*#{escape(b)}"
|
299
299
|
final = true
|
300
300
|
end
|
301
|
-
|
301
|
+
end
|
302
302
|
str += "*" unless final
|
303
303
|
eq(ber.first.to_s, str)
|
304
304
|
when 0xa5 # context-specific constructed 5, "greaterOrEqual"
|
@@ -550,10 +550,10 @@ class Net::LDAP::Filter
|
|
550
550
|
[self.class.eq(@left, @right).to_ber].to_ber_contextspecific(2)
|
551
551
|
when :and
|
552
552
|
ary = [@left.coalesce(:and), @right.coalesce(:and)].flatten
|
553
|
-
ary.map
|
553
|
+
ary.map(&:to_ber).to_ber_contextspecific(0)
|
554
554
|
when :or
|
555
555
|
ary = [@left.coalesce(:or), @right.coalesce(:or)].flatten
|
556
|
-
ary.map
|
556
|
+
ary.map(&:to_ber).to_ber_contextspecific(1)
|
557
557
|
when :not
|
558
558
|
[@left.to_ber].to_ber_contextspecific(2)
|
559
559
|
end
|
data/lib/net/ldap/pdu.rb
CHANGED
@@ -74,6 +74,7 @@ class Net::LDAP::PDU
|
|
74
74
|
attr_reader :search_referrals
|
75
75
|
attr_reader :search_parameters
|
76
76
|
attr_reader :bind_parameters
|
77
|
+
attr_reader :extended_response
|
77
78
|
|
78
79
|
##
|
79
80
|
# Returns RFC-2251 Controls if any.
|
@@ -120,7 +121,7 @@ class Net::LDAP::PDU
|
|
120
121
|
when UnbindRequest
|
121
122
|
parse_unbind_request(ber_object[1])
|
122
123
|
when ExtendedResponse
|
123
|
-
|
124
|
+
parse_extended_response(ber_object[1])
|
124
125
|
else
|
125
126
|
raise LdapPduError.new("unknown pdu-type: #{@app_tag}")
|
126
127
|
end
|
@@ -174,12 +175,35 @@ class Net::LDAP::PDU
|
|
174
175
|
@ldap_result = {
|
175
176
|
:resultCode => sequence[0],
|
176
177
|
:matchedDN => sequence[1],
|
177
|
-
:errorMessage => sequence[2]
|
178
|
+
:errorMessage => sequence[2],
|
178
179
|
}
|
179
180
|
parse_search_referral(sequence[3]) if @ldap_result[:resultCode] == Net::LDAP::ResultCodeReferral
|
180
181
|
end
|
181
182
|
private :parse_ldap_result
|
182
183
|
|
184
|
+
##
|
185
|
+
# Parse an extended response
|
186
|
+
#
|
187
|
+
# http://www.ietf.org/rfc/rfc2251.txt
|
188
|
+
#
|
189
|
+
# Each Extended operation consists of an Extended request and an
|
190
|
+
# Extended response.
|
191
|
+
#
|
192
|
+
# ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
|
193
|
+
# requestName [0] LDAPOID,
|
194
|
+
# requestValue [1] OCTET STRING OPTIONAL }
|
195
|
+
|
196
|
+
def parse_extended_response(sequence)
|
197
|
+
sequence.length >= 3 or raise Net::LDAP::PDU::Error, "Invalid LDAP result length."
|
198
|
+
@ldap_result = {
|
199
|
+
:resultCode => sequence[0],
|
200
|
+
:matchedDN => sequence[1],
|
201
|
+
:errorMessage => sequence[2],
|
202
|
+
}
|
203
|
+
@extended_response = sequence[3]
|
204
|
+
end
|
205
|
+
private :parse_extended_response
|
206
|
+
|
183
207
|
##
|
184
208
|
# A Bind Response may have an additional field, ID [7], serverSaslCreds,
|
185
209
|
# per RFC 2251 pgh 4.2.3.
|
data/lib/net/ldap/version.rb
CHANGED
data/lib/net/snmp.rb
CHANGED
@@ -12,7 +12,7 @@ module Net
|
|
12
12
|
2 => :integer, # Gauge32 or Unsigned32, (RFC2578 sec 2)
|
13
13
|
3 => :integer # TimeTicks32, (RFC2578 sec 2)
|
14
14
|
},
|
15
|
-
:constructed => {}
|
15
|
+
:constructed => {},
|
16
16
|
},
|
17
17
|
:context_specific => {
|
18
18
|
:primitive => {},
|
@@ -20,8 +20,8 @@ module Net
|
|
20
20
|
0 => :array, # GetRequest PDU (RFC1157 pgh 4.1.2)
|
21
21
|
1 => :array, # GetNextRequest PDU (RFC1157 pgh 4.1.3)
|
22
22
|
2 => :array # GetResponse PDU (RFC1157 pgh 4.1.4)
|
23
|
-
}
|
24
|
-
}
|
23
|
+
},
|
24
|
+
},
|
25
25
|
})
|
26
26
|
|
27
27
|
# SNMP 32-bit counter.
|
@@ -70,7 +70,7 @@ module Net
|
|
70
70
|
:get_next_request,
|
71
71
|
:get_response,
|
72
72
|
:set_request,
|
73
|
-
:trap
|
73
|
+
:trap,
|
74
74
|
]
|
75
75
|
ErrorStatusCodes = { # Per RFC1157, pgh 4.1.1
|
76
76
|
0 => "noError",
|
@@ -78,7 +78,7 @@ module Net
|
|
78
78
|
2 => "noSuchName",
|
79
79
|
3 => "badValue",
|
80
80
|
4 => "readOnly",
|
81
|
-
5 => "genErr"
|
81
|
+
5 => "genErr",
|
82
82
|
}
|
83
83
|
|
84
84
|
class << self
|
@@ -148,7 +148,7 @@ module Net
|
|
148
148
|
# data[2] is error_index, always zero.
|
149
149
|
send :error_status=, 0
|
150
150
|
send :error_index=, 0
|
151
|
-
data[3].each do |n,v|
|
151
|
+
data[3].each do |n, v|
|
152
152
|
# A variable-binding, of which there may be several,
|
153
153
|
# consists of an OID and a BER null.
|
154
154
|
# We're ignoring the null, we might want to verify it instead.
|
@@ -166,7 +166,7 @@ module Net
|
|
166
166
|
send :request_id=, data[0].to_i
|
167
167
|
send :error_status=, data[1].to_i
|
168
168
|
send :error_index=, data[2].to_i
|
169
|
-
data[3].each do |n,v|
|
169
|
+
data[3].each do |n, v|
|
170
170
|
# A variable-binding, of which there may be several,
|
171
171
|
# consists of an OID and a BER null.
|
172
172
|
# We're ignoring the null, we might want to verify it instead.
|
@@ -177,7 +177,7 @@ module Net
|
|
177
177
|
|
178
178
|
|
179
179
|
def version= ver
|
180
|
-
unless [0,2].include?(ver)
|
180
|
+
unless [0, 2].include?(ver)
|
181
181
|
raise Error.new("unknown snmp-version: #{ver}")
|
182
182
|
end
|
183
183
|
@version = ver
|
@@ -191,7 +191,7 @@ module Net
|
|
191
191
|
end
|
192
192
|
|
193
193
|
def error_status= es
|
194
|
-
unless ErrorStatusCodes.
|
194
|
+
unless ErrorStatusCodes.key?(es)
|
195
195
|
raise Error.new("unknown error-status: #{es}")
|
196
196
|
end
|
197
197
|
@error_status = es
|
@@ -227,10 +227,10 @@ module Net
|
|
227
227
|
error_status.to_ber,
|
228
228
|
error_index.to_ber,
|
229
229
|
[
|
230
|
-
@variables.map
|
230
|
+
@variables.map do|n, v|
|
231
231
|
[n.to_ber_oid, Net::BER::BerIdentifiedNull.new.to_ber].to_ber_sequence
|
232
|
-
|
233
|
-
].to_ber_sequence
|
232
|
+
end,
|
233
|
+
].to_ber_sequence,
|
234
234
|
].to_ber_contextspecific(0)
|
235
235
|
when :get_next_request
|
236
236
|
[
|
@@ -238,10 +238,10 @@ module Net
|
|
238
238
|
error_status.to_ber,
|
239
239
|
error_index.to_ber,
|
240
240
|
[
|
241
|
-
@variables.map
|
241
|
+
@variables.map do|n, v|
|
242
242
|
[n.to_ber_oid, Net::BER::BerIdentifiedNull.new.to_ber].to_ber_sequence
|
243
|
-
|
244
|
-
].to_ber_sequence
|
243
|
+
end,
|
244
|
+
].to_ber_sequence,
|
245
245
|
].to_ber_contextspecific(1)
|
246
246
|
when :get_response
|
247
247
|
[
|
@@ -249,10 +249,10 @@ module Net
|
|
249
249
|
error_status.to_ber,
|
250
250
|
error_index.to_ber,
|
251
251
|
[
|
252
|
-
@variables.map
|
252
|
+
@variables.map do|n, v|
|
253
253
|
[n.to_ber_oid, v.to_ber].to_ber_sequence
|
254
|
-
|
255
|
-
].to_ber_sequence
|
254
|
+
end,
|
255
|
+
].to_ber_sequence,
|
256
256
|
].to_ber_contextspecific(2)
|
257
257
|
else
|
258
258
|
raise Error.new( "unknown pdu-type: #{pdu_type}" )
|
@@ -6,7 +6,7 @@ class TestBERArrayExtension < Test::Unit::TestCase
|
|
6
6
|
control_codes << ['1.2.3'.to_ber, true.to_ber].to_ber_sequence
|
7
7
|
control_codes << ['1.7.9'.to_ber, false.to_ber].to_ber_sequence
|
8
8
|
control_codes = control_codes.to_ber_sequence
|
9
|
-
res = [['1.2.3', true],['1.7.9',false]].to_ber_control
|
9
|
+
res = [['1.2.3', true], ['1.7.9', false]].to_ber_control
|
10
10
|
assert_equal control_codes, res
|
11
11
|
end
|
12
12
|
|
data/test/ber/test_ber.rb
CHANGED
@@ -14,7 +14,7 @@ class TestAddIntegration < LDAPIntegrationTestCase
|
|
14
14
|
uid: "added-user1",
|
15
15
|
cn: "added-user1",
|
16
16
|
sn: "added-user1",
|
17
|
-
mail: "added-user1@rubyldap.com"
|
17
|
+
mail: "added-user1@rubyldap.com",
|
18
18
|
}
|
19
19
|
|
20
20
|
assert @ldap.add(dn: @dn, attributes: attrs), @ldap.get_operation_result.inspect
|
@@ -12,7 +12,7 @@ class TestDeleteIntegration < LDAPIntegrationTestCase
|
|
12
12
|
uid: "delete-user1",
|
13
13
|
cn: "delete-user1",
|
14
14
|
sn: "delete-user1",
|
15
|
-
mail: "delete-user1@rubyldap.com"
|
15
|
+
mail: "delete-user1@rubyldap.com",
|
16
16
|
}
|
17
17
|
unless @ldap.search(base: @dn, scope: Net::LDAP::SearchScope_BaseObject)
|
18
18
|
assert @ldap.add(dn: @dn, attributes: attrs), @ldap.get_operation_result.inspect
|
@@ -63,7 +63,7 @@ class TestBindIntegration < LDAPIntegrationTestCase
|
|
63
63
|
uid: "nested-open-added-user1",
|
64
64
|
cn: "nested-open-added-user1",
|
65
65
|
sn: "nested-open-added-user1",
|
66
|
-
mail: "nested-open-added-user1@rubyldap.com"
|
66
|
+
mail: "nested-open-added-user1@rubyldap.com",
|
67
67
|
}
|
68
68
|
|
69
69
|
@ldap.authenticate "cn=admin,dc=rubyldap,dc=com", "passworD1"
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class TestPasswordModifyIntegration < LDAPIntegrationTestCase
|
4
|
+
def setup
|
5
|
+
super
|
6
|
+
@ldap.authenticate 'cn=admin,dc=rubyldap,dc=com', 'passworD1'
|
7
|
+
|
8
|
+
@dn = 'uid=modify-password-user1,ou=People,dc=rubyldap,dc=com'
|
9
|
+
|
10
|
+
attrs = {
|
11
|
+
objectclass: %w(top inetOrgPerson organizationalPerson person),
|
12
|
+
uid: 'modify-password-user1',
|
13
|
+
cn: 'modify-password-user1',
|
14
|
+
sn: 'modify-password-user1',
|
15
|
+
mail: 'modify-password-user1@rubyldap.com',
|
16
|
+
userPassword: 'passworD1',
|
17
|
+
}
|
18
|
+
unless @ldap.search(base: @dn, scope: Net::LDAP::SearchScope_BaseObject)
|
19
|
+
assert @ldap.add(dn: @dn, attributes: attrs), @ldap.get_operation_result.inspect
|
20
|
+
end
|
21
|
+
assert @ldap.search(base: @dn, scope: Net::LDAP::SearchScope_BaseObject)
|
22
|
+
|
23
|
+
@auth = {
|
24
|
+
method: :simple,
|
25
|
+
username: @dn,
|
26
|
+
password: 'passworD1',
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_password_modify
|
31
|
+
assert @ldap.password_modify(dn: @dn,
|
32
|
+
auth: @auth,
|
33
|
+
old_password: 'passworD1',
|
34
|
+
new_password: 'passworD2')
|
35
|
+
|
36
|
+
assert @ldap.get_operation_result.extended_response.nil?,
|
37
|
+
'Should not have generated a new password'
|
38
|
+
|
39
|
+
refute @ldap.bind(username: @dn, password: 'passworD1', method: :simple),
|
40
|
+
'Old password should no longer be valid'
|
41
|
+
|
42
|
+
assert @ldap.bind(username: @dn, password: 'passworD2', method: :simple),
|
43
|
+
'New password should be valid'
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_password_modify_generate
|
47
|
+
assert @ldap.password_modify(dn: @dn,
|
48
|
+
auth: @auth,
|
49
|
+
old_password: 'passworD1')
|
50
|
+
|
51
|
+
generated_password = @ldap.get_operation_result.extended_response[0][0]
|
52
|
+
|
53
|
+
assert generated_password, 'Should have generated a password'
|
54
|
+
|
55
|
+
refute @ldap.bind(username: @dn, password: 'passworD1', method: :simple),
|
56
|
+
'Old password should no longer be valid'
|
57
|
+
|
58
|
+
assert @ldap.bind(username: @dn, password: generated_password, method: :simple),
|
59
|
+
'New password should be valid'
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_password_modify_generate_no_old_password
|
63
|
+
assert @ldap.password_modify(dn: @dn,
|
64
|
+
auth: @auth)
|
65
|
+
|
66
|
+
generated_password = @ldap.get_operation_result.extended_response[0][0]
|
67
|
+
|
68
|
+
assert generated_password, 'Should have generated a password'
|
69
|
+
|
70
|
+
refute @ldap.bind(username: @dn, password: 'passworD1', method: :simple),
|
71
|
+
'Old password should no longer be valid'
|
72
|
+
|
73
|
+
assert @ldap.bind(username: @dn, password: generated_password, method: :simple),
|
74
|
+
'New password should be valid'
|
75
|
+
end
|
76
|
+
|
77
|
+
def teardown
|
78
|
+
@ldap.delete dn: @dn
|
79
|
+
end
|
80
|
+
end
|
data/test/test_auth_adapter.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class TestAuthAdapter < Test::Unit::TestCase
|
4
|
-
|
5
|
-
|
4
|
+
class FakeSocket
|
5
|
+
def initialize(*args)
|
6
|
+
end
|
7
|
+
end
|
6
8
|
|
7
|
-
|
9
|
+
def test_undefined_auth_adapter
|
10
|
+
conn = Net::LDAP::Connection.new(host: 'ldap.example.com', port: 379, :socket_class => FakeSocket)
|
8
11
|
assert_raise Net::LDAP::AuthMethodUnsupportedError, "Unsupported auth method (foo)" do
|
9
12
|
conn.bind(method: :foo)
|
10
13
|
end
|
data/test/test_dn.rb
CHANGED
@@ -13,17 +13,17 @@ class TestDN < Test::Unit::TestCase
|
|
13
13
|
|
14
14
|
def test_to_a
|
15
15
|
dn = Net::LDAP::DN.new('cn=James, ou=Company\\,\\20LLC')
|
16
|
-
assert_equal ['cn','James','ou','Company, LLC'], dn.to_a
|
16
|
+
assert_equal ['cn', 'James', 'ou', 'Company, LLC'], dn.to_a
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_to_a_parenthesis
|
20
20
|
dn = Net::LDAP::DN.new('cn = \ James , ou = "Comp\28ny" ')
|
21
|
-
assert_equal ['cn',' James','ou','Comp(ny'], dn.to_a
|
21
|
+
assert_equal ['cn', ' James', 'ou', 'Comp(ny'], dn.to_a
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_to_a_hash_symbol
|
25
25
|
dn = Net::LDAP::DN.new('1.23.4= #A3B4D5 ,ou=Company')
|
26
|
-
assert_equal ['1.23.4','#A3B4D5','ou','Company'], dn.to_a
|
26
|
+
assert_equal ['1.23.4', '#A3B4D5', 'ou', 'Company'], dn.to_a
|
27
27
|
end
|
28
28
|
|
29
29
|
# TODO: raise a more specific exception than RuntimeError
|
data/test/test_filter.rb
CHANGED
@@ -13,11 +13,11 @@ class TestFilter < Test::Unit::TestCase
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_invalid_filter
|
16
|
-
assert_raises(Net::LDAP::OperatorError)
|
16
|
+
assert_raises(Net::LDAP::OperatorError) do
|
17
17
|
# This test exists to prove that our constructor blocks unknown filter
|
18
18
|
# types. All filters must be constructed using helpers.
|
19
19
|
Filter.__send__(:new, :xx, nil, nil)
|
20
|
-
|
20
|
+
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def test_to_s
|
@@ -144,7 +144,7 @@ class TestFilterRSpec < Test::Unit::TestCase
|
|
144
144
|
'(:dn:2.4.8.10:=Dino)',
|
145
145
|
'(cn:dn:1.2.3.4.5:=John Smith)',
|
146
146
|
'(sn:dn:2.4.6.8.10:=Barbara Jones)',
|
147
|
-
'(&(sn:dn:2.4.6.8.10:=Barbara Jones))'
|
147
|
+
'(&(sn:dn:2.4.6.8.10:=Barbara Jones))',
|
148
148
|
].each_with_index do |filter_str, index|
|
149
149
|
define_method "test_decode_filter_#{index}" do
|
150
150
|
filter = Net::LDAP::Filter.from_rfc2254(filter_str)
|
@@ -195,7 +195,7 @@ class TestFilterRSpec < Test::Unit::TestCase
|
|
195
195
|
"foo" "\\2A\\5C" "bar",
|
196
196
|
"foo" "\\2a\\5c" "bar",
|
197
197
|
"foo" "\\2A\\5c" "bar",
|
198
|
-
"foo" "\\2a\\5C" "bar"
|
198
|
+
"foo" "\\2a\\5C" "bar",
|
199
199
|
].each do |escaped|
|
200
200
|
# unescapes escaped characters
|
201
201
|
filter = Net::LDAP::Filter.eq("objectclass", "#{escaped}*#{escaped}*#{escaped}")
|