Skip to content

Commit 4c24b4e

Browse files
author
Chris Dwan
committed
Added encoding of sort controls if passed in as an option to the search
1 parent b94bba9 commit 4c24b4e

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

lib/net/ldap.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,8 @@ class LdapError < StandardError; end
336336

337337
module LDAPControls
338338
PAGED_RESULTS = "1.2.840.113556.1.4.319" # Microsoft evil from RFC 2696
339+
SORT_REQUEST = "1.2.840.113556.1.4.473"
340+
SORT_RESPONSE = "1.2.840.113556.1.4.474"
339341
DELETE_TREE = "1.2.840.113556.1.4.805"
340342
end
341343

@@ -1328,6 +1330,35 @@ def bind_gss_spnego(auth)
13281330
end
13291331
private :bind_gss_spnego
13301332

1333+
1334+
#--
1335+
# Allow the caller to specify a sort control
1336+
#
1337+
# The format of the sort control needs to be:
1338+
#
1339+
# :sort_control => ["cn"] # just a string
1340+
# or
1341+
# :sort_control => [["cn", "matchingRule", true]] #attribute, matchingRule, direction (true / false)
1342+
# or
1343+
# :sort_control => ["givenname","sn"] #multiple strings or arrays
1344+
#
1345+
def encode_sort_controls(sort_definitions)
1346+
return sort_definitions unless sort_definitions
1347+
1348+
sort_control_values = sort_definitions.map do |control|
1349+
control = Array(control) # if there is only an attribute name as a string then infer the orderinrule and reverseorder
1350+
control[0] = String(control[0]).to_ber,
1351+
control[1] = String(control[1]).to_ber,
1352+
control[2] = (control[2] == true).to_ber
1353+
control.to_ber_sequence
1354+
end
1355+
sort_control = [
1356+
Net::LDAP::LDAPControls::SORT_REQUEST.to_ber,
1357+
false.to_ber,
1358+
sort_control_values.to_ber_sequence.to_s.to_ber
1359+
].to_ber_sequence
1360+
end
1361+
13311362
#--
13321363
# Alternate implementation, this yields each search entry to the caller as
13331364
# it are received.
@@ -1353,6 +1384,7 @@ def search(args = {})
13531384
scope = args[:scope] || Net::LDAP::SearchScope_WholeSubtree
13541385
raise Net::LDAP::LdapError, "invalid search scope" unless Net::LDAP::SearchScopes.include?(scope)
13551386

1387+
sort_control = encode_sort_controls(args.fetch(:sort_controls){ false })
13561388
# An interesting value for the size limit would be close to A/D's
13571389
# built-in page limit of 1000 records, but openLDAP newer than version
13581390
# 2.2.0 chokes on anything bigger than 126. You get a silent error that
@@ -1408,6 +1440,8 @@ def search(args = {})
14081440
false.to_ber,
14091441
rfc2696_cookie.map{ |v| v.to_ber}.to_ber_sequence.to_s.to_ber
14101442
].to_ber_sequence if paged_searches_supported
1443+
1444+
controls << sort_control if sort_control
14111445
controls = controls.to_ber_contextspecific(0)
14121446

14131447
pkt = [next_msgid.to_ber, request, controls].to_ber_sequence

0 commit comments

Comments
 (0)