@@ -311,26 +311,47 @@ def encode_sort_controls(sort_definitions)
311311 # type-5 packet, which might never come. We need to support the time-limit
312312 # in the protocol.
313313 #++
314- def search ( args = { } )
315- search_filter = ( args && args [ :filter ] ) ||
316- Net ::LDAP ::Filter . eq ( "objectclass" , "*" )
317- search_filter = Net ::LDAP ::Filter . construct ( search_filter ) if search_filter . is_a? ( String )
318- search_base = ( args && args [ :base ] ) || "dc=example, dc=com"
319- search_attributes = ( ( args && args [ :attributes ] ) || [ ] ) . map { |attr | attr . to_s . to_ber }
320- return_referrals = args && args [ :return_referrals ] == true
321- sizelimit = ( args && args [ :size ] . to_i ) || 0
322- timelimit = ( args && args [ :time ] . to_i ) || 0
323- raise Net ::LDAP ::LdapError , "invalid search-size" unless sizelimit >= 0
324- paged_searches_supported = ( args && args [ :paged_searches_supported ] )
325-
326- attributes_only = ( args and args [ :attributes_only ] == true )
327- scope = args [ :scope ] || Net ::LDAP ::SearchScope_WholeSubtree
314+ def search ( args = nil )
315+ args ||= { }
316+
317+ # filtering, scoping, search base
318+ # filter: https://tools.ietf.org/html/rfc4511#section-4.5.1.7
319+ # base: https://tools.ietf.org/html/rfc4511#section-4.5.1.1
320+ # scope: https://tools.ietf.org/html/rfc4511#section-4.5.1.2
321+ filter = args [ :filter ] || Net ::LDAP ::Filter . eq ( "objectClass" , "*" )
322+ base = args [ :base ]
323+ scope = args [ :scope ] || Net ::LDAP ::SearchScope_WholeSubtree
324+
325+ # attr handling
326+ # attrs: https://tools.ietf.org/html/rfc4511#section-4.5.1.8
327+ # attrs_only: https://tools.ietf.org/html/rfc4511#section-4.5.1.6
328+ attrs = Array ( args [ :attributes ] )
329+ attrs_only = args [ :attributes_only ] == true
330+
331+ # references
332+ # refs: https://tools.ietf.org/html/rfc4511#section-4.5.3
333+ # deref: https://tools.ietf.org/html/rfc4511#section-4.5.1.3
334+ refs = args [ :return_referrals ] == true
335+ deref = args [ :deref ] || Net ::LDAP ::DerefAliases_Never
336+
337+ # limiting, paging, sorting
338+ # size: https://tools.ietf.org/html/rfc4511#section-4.5.1.4
339+ # time: https://tools.ietf.org/html/rfc4511#section-4.5.1.5
340+ size = args [ :size ] . to_i
341+ time = args [ :time ] . to_i
342+ paged = args [ :paged_searches_supported ]
343+ sort = args . fetch ( :sort_controls , false )
344+
345+ # arg validation
346+ raise Net ::LDAP ::LdapError , "search base is required" unless base
347+ raise Net ::LDAP ::LdapError , "invalid search-size" unless size >= 0
328348 raise Net ::LDAP ::LdapError , "invalid search scope" unless Net ::LDAP ::SearchScopes . include? ( scope )
349+ raise Net ::LDAP ::LdapError , "invalid alias dereferencing value" unless Net ::LDAP ::DerefAliasesArray . include? ( deref )
329350
330- sort_control = encode_sort_controls ( args . fetch ( :sort_controls ) { false } )
331-
332- deref = args [ :deref ] || Net :: LDAP :: DerefAliases_Never
333- raise Net :: LDAP :: LdapError . new ( "invalid alias dereferencing value" ) unless Net :: LDAP :: DerefAliasesArray . include? ( deref )
351+ # arg transforms
352+ filter = Net :: LDAP :: Filter . construct ( filter ) if filter . is_a? ( String )
353+ ber_attrs = attrs . map { | attr | attr . to_s . to_ber }
354+ ber_sort = encode_sort_controls ( sort )
334355
335356 # An interesting value for the size limit would be close to A/D's
336357 # built-in page limit of 1000 records, but openLDAP newer than version
@@ -357,36 +378,36 @@ def search(args = {})
357378 n_results = 0
358379
359380 instrument "search.net_ldap_connection" ,
360- : filter => search_filter ,
361- : base => search_base ,
362- : scope => scope ,
363- : limit => sizelimit ,
364- :timelimit => timelimit ,
365- : sort => sort_control ,
366- : referrals => return_referrals ,
367- : deref => deref ,
368- : attributes => search_attributes do |payload |
381+ filter : filter ,
382+ base : base ,
383+ scope : scope ,
384+ limit : size ,
385+ time : time ,
386+ sort : sort ,
387+ referrals : refs ,
388+ deref : deref ,
389+ attributes : attrs do |payload |
369390 loop do
370391 # should collect this into a private helper to clarify the structure
371392 query_limit = 0
372- if sizelimit > 0
373- if paged_searches_supported
374- query_limit = ( ( ( sizelimit - n_results ) < 126 ) ? ( sizelimit -
393+ if size > 0
394+ if paged
395+ query_limit = ( ( ( size - n_results ) < 126 ) ? ( size -
375396 n_results ) : 0 )
376397 else
377- query_limit = sizelimit
398+ query_limit = size
378399 end
379400 end
380401
381402 request = [
382- search_base . to_ber ,
403+ base . to_ber ,
383404 scope . to_ber_enumerated ,
384405 deref . to_ber_enumerated ,
385406 query_limit . to_ber , # size limit
386407 timelimit . to_ber ,
387- attributes_only . to_ber ,
388- search_filter . to_ber ,
389- search_attributes . to_ber_sequence
408+ attrs_only . to_ber ,
409+ filter . to_ber ,
410+ ber_attrs . to_ber_sequence
390411 ] . to_ber_appsequence ( 3 )
391412
392413 # rfc2696_cookie sometimes contains binary data from Microsoft Active Directory
@@ -400,8 +421,8 @@ def search(args = {})
400421 # Criticality MUST be false to interoperate with normal LDAPs.
401422 false . to_ber ,
402423 rfc2696_cookie . map { |v | v . to_ber } . to_ber_sequence . to_s . to_ber
403- ] . to_ber_sequence if paged_searches_supported
404- controls << sort_control if sort_control
424+ ] . to_ber_sequence if paged
425+ controls << ber_sort if ber_sort
405426 controls = controls . empty? ? nil : controls . to_ber_contextspecific ( 0 )
406427
407428 write ( request , controls )
@@ -415,7 +436,7 @@ def search(args = {})
415436 n_results += 1
416437 yield pdu . search_entry if block_given?
417438 when Net ::LDAP ::PDU ::SearchResultReferral
418- if return_referrals
439+ if refs
419440 if block_given?
420441 se = Net ::LDAP ::Entry . new
421442 se [ :search_referrals ] = ( pdu . search_referrals || [ ] )
@@ -425,7 +446,7 @@ def search(args = {})
425446 when Net ::LDAP ::PDU ::SearchResult
426447 result_pdu = pdu
427448 controls = pdu . result_controls
428- if return_referrals && pdu . result_code == 10
449+ if refs && pdu . result_code == 10
429450 if block_given?
430451 se = Net ::LDAP ::Entry . new
431452 se [ :search_referrals ] = ( pdu . search_referrals || [ ] )
0 commit comments