@@ -311,26 +311,45 @@ 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
- raise Net ::LDAP ::LdapError , "invalid search-size" unless sizelimit >= 0
323
- paged_searches_supported = ( args && args [ :paged_searches_supported ] )
324
-
325
- attributes_only = ( args and args [ :attributes_only ] == true )
326
- 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
+ size = args [ :size ] . to_i
340
+ paged = args [ :paged_searches_supported ]
341
+ sort = args . fetch ( :sort_controls , false )
342
+
343
+ # arg validation
344
+ raise Net ::LDAP ::LdapError , "search base is required" unless base
345
+ raise Net ::LDAP ::LdapError , "invalid search-size" unless size >= 0
327
346
raise Net ::LDAP ::LdapError , "invalid search scope" unless Net ::LDAP ::SearchScopes . include? ( scope )
347
+ raise Net ::LDAP ::LdapError , "invalid alias dereferencing value" unless Net ::LDAP ::DerefAliasesArray . include? ( deref )
328
348
329
- sort_control = encode_sort_controls ( args . fetch ( :sort_controls ) { false } )
330
-
331
- deref = args [ :deref ] || Net ::LDAP ::DerefAliases_Never
332
- raise Net ::LDAP ::LdapError . new ( "invalid alias dereferencing value" ) unless Net ::LDAP ::DerefAliasesArray . include? ( deref )
333
-
349
+ # arg transforms
350
+ filter = Net ::LDAP ::Filter . construct ( filter ) if filter . is_a? ( String )
351
+ ber_attrs = attrs . map { |attr | attr . to_s . to_ber }
352
+ ber_sort = encode_sort_controls ( sort )
334
353
335
354
# An interesting value for the size limit would be close to A/D's
336
355
# built-in page limit of 1000 records, but openLDAP newer than version
@@ -357,35 +376,35 @@ def search(args = {})
357
376
n_results = 0
358
377
359
378
instrument "search.net_ldap_connection" ,
360
- : filter => search_filter ,
361
- : base => search_base ,
362
- : scope => scope ,
363
- : limit => sizelimit ,
364
- : sort => sort_control ,
365
- : referrals => return_referrals ,
366
- : deref => deref ,
367
- : attributes => search_attributes do |payload |
379
+ filter : filter ,
380
+ base : base ,
381
+ scope : scope ,
382
+ limit : size ,
383
+ sort : sort ,
384
+ referrals : refs ,
385
+ deref : deref ,
386
+ attributes : attrs do |payload |
368
387
loop do
369
388
# should collect this into a private helper to clarify the structure
370
389
query_limit = 0
371
- if sizelimit > 0
372
- if paged_searches_supported
373
- query_limit = ( ( ( sizelimit - n_results ) < 126 ) ? ( sizelimit -
390
+ if size > 0
391
+ if paged
392
+ query_limit = ( ( ( size - n_results ) < 126 ) ? ( size -
374
393
n_results ) : 0 )
375
394
else
376
- query_limit = sizelimit
395
+ query_limit = size
377
396
end
378
397
end
379
398
380
399
request = [
381
- search_base . to_ber ,
400
+ base . to_ber ,
382
401
scope . to_ber_enumerated ,
383
402
deref . to_ber_enumerated ,
384
403
query_limit . to_ber , # size limit
385
404
0 . to_ber ,
386
- attributes_only . to_ber ,
387
- search_filter . to_ber ,
388
- search_attributes . to_ber_sequence
405
+ attrs_only . to_ber ,
406
+ filter . to_ber ,
407
+ ber_attrs . to_ber_sequence
389
408
] . to_ber_appsequence ( 3 )
390
409
391
410
# rfc2696_cookie sometimes contains binary data from Microsoft Active Directory
@@ -399,8 +418,8 @@ def search(args = {})
399
418
# Criticality MUST be false to interoperate with normal LDAPs.
400
419
false . to_ber ,
401
420
rfc2696_cookie . map { |v | v . to_ber } . to_ber_sequence . to_s . to_ber
402
- ] . to_ber_sequence if paged_searches_supported
403
- controls << sort_control if sort_control
421
+ ] . to_ber_sequence if paged
422
+ controls << ber_sort if ber_sort
404
423
controls = controls . empty? ? nil : controls . to_ber_contextspecific ( 0 )
405
424
406
425
write ( request , controls )
@@ -414,7 +433,7 @@ def search(args = {})
414
433
n_results += 1
415
434
yield pdu . search_entry if block_given?
416
435
when Net ::LDAP ::PDU ::SearchResultReferral
417
- if return_referrals
436
+ if refs
418
437
if block_given?
419
438
se = Net ::LDAP ::Entry . new
420
439
se [ :search_referrals ] = ( pdu . search_referrals || [ ] )
@@ -424,7 +443,7 @@ def search(args = {})
424
443
when Net ::LDAP ::PDU ::SearchResult
425
444
result_pdu = pdu
426
445
controls = pdu . result_controls
427
- if return_referrals && pdu . result_code == 10
446
+ if refs && pdu . result_code == 10
428
447
if block_given?
429
448
se = Net ::LDAP ::Entry . new
430
449
se [ :search_referrals ] = ( pdu . search_referrals || [ ] )
0 commit comments