@@ -311,26 +311,47 @@ def encode_sort_controls(sort_definitions)
311
311
# type-5 packet, which might never come. We need to support the time-limit
312
312
# in the protocol.
313
313
#++
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
328
348
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 )
329
350
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 )
334
355
335
356
# An interesting value for the size limit would be close to A/D's
336
357
# built-in page limit of 1000 records, but openLDAP newer than version
@@ -357,36 +378,36 @@ def search(args = {})
357
378
n_results = 0
358
379
359
380
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 |
369
390
loop do
370
391
# should collect this into a private helper to clarify the structure
371
392
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 -
375
396
n_results ) : 0 )
376
397
else
377
- query_limit = sizelimit
398
+ query_limit = size
378
399
end
379
400
end
380
401
381
402
request = [
382
- search_base . to_ber ,
403
+ base . to_ber ,
383
404
scope . to_ber_enumerated ,
384
405
deref . to_ber_enumerated ,
385
406
query_limit . to_ber , # size limit
386
407
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
390
411
] . to_ber_appsequence ( 3 )
391
412
392
413
# rfc2696_cookie sometimes contains binary data from Microsoft Active Directory
@@ -400,8 +421,8 @@ def search(args = {})
400
421
# Criticality MUST be false to interoperate with normal LDAPs.
401
422
false . to_ber ,
402
423
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
405
426
controls = controls . empty? ? nil : controls . to_ber_contextspecific ( 0 )
406
427
407
428
write ( request , controls )
@@ -415,7 +436,7 @@ def search(args = {})
415
436
n_results += 1
416
437
yield pdu . search_entry if block_given?
417
438
when Net ::LDAP ::PDU ::SearchResultReferral
418
- if return_referrals
439
+ if refs
419
440
if block_given?
420
441
se = Net ::LDAP ::Entry . new
421
442
se [ :search_referrals ] = ( pdu . search_referrals || [ ] )
@@ -425,7 +446,7 @@ def search(args = {})
425
446
when Net ::LDAP ::PDU ::SearchResult
426
447
result_pdu = pdu
427
448
controls = pdu . result_controls
428
- if return_referrals && pdu . result_code == 10
449
+ if refs && pdu . result_code == 10
429
450
if block_given?
430
451
se = Net ::LDAP ::Entry . new
431
452
se [ :search_referrals ] = ( pdu . search_referrals || [ ] )
0 commit comments