Skip to content

Commit 77e5899

Browse files
committed
Merge branch 'master' into open-integration-tests
Conflicts: lib/net/ldap/connection.rb test/test_ldap_connection.rb
2 parents bd4f3fd + ea124f2 commit 77e5899

File tree

3 files changed

+63
-42
lines changed

3 files changed

+63
-42
lines changed

lib/net/ldap/connection.rb

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -350,26 +350,45 @@ def encode_sort_controls(sort_definitions)
350350
# type-5 packet, which might never come. We need to support the time-limit
351351
# in the protocol.
352352
#++
353-
def search(args = {})
354-
search_filter = (args && args[:filter]) ||
355-
Net::LDAP::Filter.eq("objectclass", "*")
356-
search_filter = Net::LDAP::Filter.construct(search_filter) if search_filter.is_a?(String)
357-
search_base = (args && args[:base]) || "dc=example, dc=com"
358-
search_attributes = ((args && args[:attributes]) || []).map { |attr| attr.to_s.to_ber}
359-
return_referrals = args && args[:return_referrals] == true
360-
sizelimit = (args && args[:size].to_i) || 0
361-
raise Net::LDAP::LdapError, "invalid search-size" unless sizelimit >= 0
362-
paged_searches_supported = (args && args[:paged_searches_supported])
363-
364-
attributes_only = (args and args[:attributes_only] == true)
365-
scope = args[:scope] || Net::LDAP::SearchScope_WholeSubtree
353+
def search(args = nil)
354+
args ||= {}
355+
356+
# filtering, scoping, search base
357+
# filter: https://tools.ietf.org/html/rfc4511#section-4.5.1.7
358+
# base: https://tools.ietf.org/html/rfc4511#section-4.5.1.1
359+
# scope: https://tools.ietf.org/html/rfc4511#section-4.5.1.2
360+
filter = args[:filter] || Net::LDAP::Filter.eq("objectClass", "*")
361+
base = args[:base]
362+
scope = args[:scope] || Net::LDAP::SearchScope_WholeSubtree
363+
364+
# attr handling
365+
# attrs: https://tools.ietf.org/html/rfc4511#section-4.5.1.8
366+
# attrs_only: https://tools.ietf.org/html/rfc4511#section-4.5.1.6
367+
attrs = Array(args[:attributes])
368+
attrs_only = args[:attributes_only] == true
369+
370+
# references
371+
# refs: https://tools.ietf.org/html/rfc4511#section-4.5.3
372+
# deref: https://tools.ietf.org/html/rfc4511#section-4.5.1.3
373+
refs = args[:return_referrals] == true
374+
deref = args[:deref] || Net::LDAP::DerefAliases_Never
375+
376+
# limiting, paging, sorting
377+
# size: https://tools.ietf.org/html/rfc4511#section-4.5.1.4
378+
size = args[:size].to_i
379+
paged = args[:paged_searches_supported]
380+
sort = args.fetch(:sort_controls, false)
381+
382+
# arg validation
383+
raise Net::LDAP::LdapError, "search base is required" unless base
384+
raise Net::LDAP::LdapError, "invalid search-size" unless size >= 0
366385
raise Net::LDAP::LdapError, "invalid search scope" unless Net::LDAP::SearchScopes.include?(scope)
386+
raise Net::LDAP::LdapError, "invalid alias dereferencing value" unless Net::LDAP::DerefAliasesArray.include?(deref)
367387

368-
sort_control = encode_sort_controls(args.fetch(:sort_controls){ false })
369-
370-
deref = args[:deref] || Net::LDAP::DerefAliases_Never
371-
raise Net::LDAP::LdapError.new( "invalid alias dereferencing value" ) unless Net::LDAP::DerefAliasesArray.include?(deref)
372-
388+
# arg transforms
389+
filter = Net::LDAP::Filter.construct(filter) if filter.is_a?(String)
390+
ber_attrs = attrs.map { |attr| attr.to_s.to_ber }
391+
ber_sort = encode_sort_controls(sort)
373392

374393
# An interesting value for the size limit would be close to A/D's
375394
# built-in page limit of 1000 records, but openLDAP newer than version
@@ -398,36 +417,36 @@ def search(args = {})
398417
message_id = next_msgid
399418

400419
instrument "search.net_ldap_connection",
401-
:message_id => message_id,
402-
:filter => search_filter,
403-
:base => search_base,
404-
:scope => scope,
405-
:limit => sizelimit,
406-
:sort => sort_control,
407-
:referrals => return_referrals,
408-
:deref => deref,
409-
:attributes => search_attributes do |payload|
420+
message_id: message_id,
421+
filter: filter,
422+
base: base,
423+
scope: scope,
424+
limit: size,
425+
sort: sort,
426+
referrals: refs,
427+
deref: deref,
428+
attributes: attrs do |payload|
410429
loop do
411430
# should collect this into a private helper to clarify the structure
412431
query_limit = 0
413-
if sizelimit > 0
414-
if paged_searches_supported
415-
query_limit = (((sizelimit - n_results) < 126) ? (sizelimit -
432+
if size > 0
433+
if paged
434+
query_limit = (((size - n_results) < 126) ? (size -
416435
n_results) : 0)
417436
else
418-
query_limit = sizelimit
437+
query_limit = size
419438
end
420439
end
421440

422441
request = [
423-
search_base.to_ber,
442+
base.to_ber,
424443
scope.to_ber_enumerated,
425444
deref.to_ber_enumerated,
426445
query_limit.to_ber, # size limit
427446
0.to_ber,
428-
attributes_only.to_ber,
429-
search_filter.to_ber,
430-
search_attributes.to_ber_sequence
447+
attrs_only.to_ber,
448+
filter.to_ber,
449+
ber_attrs.to_ber_sequence
431450
].to_ber_appsequence(3)
432451

433452
# rfc2696_cookie sometimes contains binary data from Microsoft Active Directory
@@ -441,8 +460,8 @@ def search(args = {})
441460
# Criticality MUST be false to interoperate with normal LDAPs.
442461
false.to_ber,
443462
rfc2696_cookie.map{ |v| v.to_ber}.to_ber_sequence.to_s.to_ber
444-
].to_ber_sequence if paged_searches_supported
445-
controls << sort_control if sort_control
463+
].to_ber_sequence if paged
464+
controls << ber_sort if ber_sort
446465
controls = controls.empty? ? nil : controls.to_ber_contextspecific(0)
447466

448467
write(request, controls, message_id)
@@ -456,7 +475,7 @@ def search(args = {})
456475
n_results += 1
457476
yield pdu.search_entry if block_given?
458477
when Net::LDAP::PDU::SearchResultReferral
459-
if return_referrals
478+
if refs
460479
if block_given?
461480
se = Net::LDAP::Entry.new
462481
se[:search_referrals] = (pdu.search_referrals || [])
@@ -466,7 +485,7 @@ def search(args = {})
466485
when Net::LDAP::PDU::SearchResult
467486
result_pdu = pdu
468487
controls = pdu.result_controls
469-
if return_referrals && pdu.result_code == 10
488+
if refs && pdu.result_code == 10
470489
if block_given?
471490
se = Net::LDAP::Entry.new
472491
se[:search_referrals] = (pdu.search_referrals || [])

test/integration/test_delete.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ def setup
1414
sn: "delete-user1",
1515
mail: "delete-user1@rubyldap.com"
1616
}
17-
assert @ldap.add(dn: @dn, attributes: attrs), @ldap.get_operation_result.inspect
17+
unless @ldap.search(base: @dn, scope: Net::LDAP::SearchScope_BaseObject)
18+
assert @ldap.add(dn: @dn, attributes: attrs), @ldap.get_operation_result.inspect
19+
end
1820
assert @ldap.search(base: @dn, scope: Net::LDAP::SearchScope_BaseObject)
1921
end
2022

test/test_ldap_connection.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ def test_bind_net_ldap_connection_event
186186
def test_search_net_ldap_connection_event
187187
# search data
188188
search_data_ber = Net::BER::BerIdentifiedArray.new([1, [
189-
"uid=user1,ou=OrgUnit2,ou=OrgUnitTop,dc=openldap,dc=ghe,dc=local",
189+
"uid=user1,ou=People,dc=rubyldap,dc=com",
190190
[ ["uid", ["user1"]] ]
191191
]])
192192
search_data_ber.ber_identifier = Net::LDAP::PDU::SearchReturnedData
@@ -201,7 +201,7 @@ def test_search_net_ldap_connection_event
201201
events = @service.subscribe "search.net_ldap_connection"
202202
unread = @service.subscribe "search_messages_unread.net_ldap_connection"
203203

204-
result = @connection.search(filter: "(uid=user1)")
204+
result = @connection.search(filter: "(uid=user1)", base: "ou=People,dc=rubyldap,dc=com")
205205
assert result.success?, "should be success"
206206

207207
# a search event

0 commit comments

Comments
 (0)