Skip to content

Commit 03ab921

Browse files
Merge pull request #411 from gwillcox-r7/add-in-ldap-control-flexibility
Add in ability for users to specify LDAP controls when conducting searches
2 parents 3d03e60 + d2d500b commit 03ab921

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

lib/net/ldap/connection.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ def search(args = nil)
425425
# this breaks when calling to_ber. (Can't force binary data to UTF-8)
426426
# we have to disable paging (even though server supports it) to get around this...
427427

428+
user_controls = args.fetch(:controls, [])
428429
controls = []
429430
controls <<
430431
[
@@ -434,7 +435,12 @@ def search(args = nil)
434435
rfc2696_cookie.map(&:to_ber).to_ber_sequence.to_s.to_ber,
435436
].to_ber_sequence if paged
436437
controls << ber_sort if ber_sort
437-
controls = controls.empty? ? nil : controls.to_ber_contextspecific(0)
438+
if controls.empty? && user_controls.empty?
439+
controls = nil
440+
else
441+
controls += user_controls
442+
controls = controls.to_ber_contextspecific(0)
443+
end
438444

439445
write(request, controls, message_id)
440446

test/test_ldap_connection.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,4 +501,43 @@ def test_search_net_ldap_connection_event
501501
# ensure no unread
502502
assert unread.empty?, "should not have any leftover unread messages"
503503
end
504+
505+
def test_search_with_controls
506+
# search data
507+
search_data_ber = Net::BER::BerIdentifiedArray.new([1, [
508+
"uid=user1,ou=People,dc=rubyldap,dc=com",
509+
[["uid", ["user1"]]],
510+
]])
511+
search_data_ber.ber_identifier = Net::LDAP::PDU::SearchReturnedData
512+
search_data = [1, search_data_ber]
513+
# search result (end of results)
514+
search_result_ber = Net::BER::BerIdentifiedArray.new([Net::LDAP::ResultCodeSuccess, "", ""])
515+
search_result_ber.ber_identifier = Net::LDAP::PDU::SearchResult
516+
search_result = [1, search_result_ber]
517+
@tcp_socket.should_receive(:read_ber).and_return(search_data)
518+
.and_return(search_result)
519+
520+
events = @service.subscribe "search.net_ldap_connection"
521+
unread = @service.subscribe "search_messages_unread.net_ldap_connection"
522+
523+
all_but_sacl_flag = 0x1 | 0x2 | 0x4 # OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION
524+
control_values = [all_but_sacl_flag].map(&:to_ber).to_ber_sequence.to_s.to_ber
525+
controls = []
526+
# LDAP_SERVER_SD_FLAGS constant definition, taken from https://ldapwiki.com/wiki/LDAP_SERVER_SD_FLAGS_OID
527+
ldap_server_sd_flags = '1.2.840.113556.1.4.801'.freeze
528+
controls << [ldap_server_sd_flags.to_ber, true.to_ber, control_values].to_ber_sequence
529+
530+
result = @connection.search(filter: "(uid=user1)", base: "ou=People,dc=rubyldap,dc=com", controls: controls)
531+
assert result.success?, "should be success"
532+
533+
# a search event
534+
payload, result = events.pop
535+
assert payload.key?(:result)
536+
assert payload.key?(:filter)
537+
assert_equal "(uid=user1)", payload[:filter].to_s
538+
assert result
539+
540+
# ensure no unread
541+
assert unread.empty?, "should not have any leftover unread messages"
542+
end
504543
end

0 commit comments

Comments
 (0)