Skip to content

Commit

Permalink
Merge pull request #411 from gwillcox-r7/add-in-ldap-control-flexibility
Browse files Browse the repository at this point in the history
Add in ability for users to specify LDAP controls when conducting searches
  • Loading branch information
HarlemSquirrel authored Jun 6, 2023
2 parents 3d03e60 + d2d500b commit 03ab921
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
8 changes: 7 additions & 1 deletion lib/net/ldap/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ def search(args = nil)
# this breaks when calling to_ber. (Can't force binary data to UTF-8)
# we have to disable paging (even though server supports it) to get around this...

user_controls = args.fetch(:controls, [])
controls = []
controls <<
[
Expand All @@ -434,7 +435,12 @@ def search(args = nil)
rfc2696_cookie.map(&:to_ber).to_ber_sequence.to_s.to_ber,
].to_ber_sequence if paged
controls << ber_sort if ber_sort
controls = controls.empty? ? nil : controls.to_ber_contextspecific(0)
if controls.empty? && user_controls.empty?
controls = nil
else
controls += user_controls
controls = controls.to_ber_contextspecific(0)
end

write(request, controls, message_id)

Expand Down
39 changes: 39 additions & 0 deletions test/test_ldap_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -501,4 +501,43 @@ def test_search_net_ldap_connection_event
# ensure no unread
assert unread.empty?, "should not have any leftover unread messages"
end

def test_search_with_controls
# search data
search_data_ber = Net::BER::BerIdentifiedArray.new([1, [
"uid=user1,ou=People,dc=rubyldap,dc=com",
[["uid", ["user1"]]],
]])
search_data_ber.ber_identifier = Net::LDAP::PDU::SearchReturnedData
search_data = [1, search_data_ber]
# search result (end of results)
search_result_ber = Net::BER::BerIdentifiedArray.new([Net::LDAP::ResultCodeSuccess, "", ""])
search_result_ber.ber_identifier = Net::LDAP::PDU::SearchResult
search_result = [1, search_result_ber]
@tcp_socket.should_receive(:read_ber).and_return(search_data)
.and_return(search_result)

events = @service.subscribe "search.net_ldap_connection"
unread = @service.subscribe "search_messages_unread.net_ldap_connection"

all_but_sacl_flag = 0x1 | 0x2 | 0x4 # OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION
control_values = [all_but_sacl_flag].map(&:to_ber).to_ber_sequence.to_s.to_ber
controls = []
# LDAP_SERVER_SD_FLAGS constant definition, taken from https://ldapwiki.com/wiki/LDAP_SERVER_SD_FLAGS_OID
ldap_server_sd_flags = '1.2.840.113556.1.4.801'.freeze
controls << [ldap_server_sd_flags.to_ber, true.to_ber, control_values].to_ber_sequence

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

# a search event
payload, result = events.pop
assert payload.key?(:result)
assert payload.key?(:filter)
assert_equal "(uid=user1)", payload[:filter].to_s
assert result

# ensure no unread
assert unread.empty?, "should not have any leftover unread messages"
end
end

0 comments on commit 03ab921

Please sign in to comment.