@@ -350,26 +350,45 @@ def encode_sort_controls(sort_definitions)
350
350
# type-5 packet, which might never come. We need to support the time-limit
351
351
# in the protocol.
352
352
#++
353
- def search ( args = { } )
354
- search_filter = ( args && args [ :filter ] ) ||
355
- Net ::LDAP ::Filter . eq ( "objectclass" , "*" )
356
- search_filter = Net ::LDAP ::Filter . construct ( search_filter ) if search_filter . is_a? ( String )
357
- search_base = ( args && args [ :base ] ) || "dc=example, dc=com"
358
- search_attributes = ( ( args && args [ :attributes ] ) || [ ] ) . map { |attr | attr . to_s . to_ber }
359
- return_referrals = args && args [ :return_referrals ] == true
360
- sizelimit = ( args && args [ :size ] . to_i ) || 0
361
- raise Net ::LDAP ::LdapError , "invalid search-size" unless sizelimit >= 0
362
- paged_searches_supported = ( args && args [ :paged_searches_supported ] )
363
-
364
- attributes_only = ( args and args [ :attributes_only ] == true )
365
- scope = args [ :scope ] || Net ::LDAP ::SearchScope_WholeSubtree
353
+ def search ( args = nil )
354
+ args ||= { }
355
+
356
+ # filtering, scoping, search base
357
+ # filter: https://tools.ietf.org/html/rfc4511#section-4.5.1.7
358
+ # base: https://tools.ietf.org/html/rfc4511#section-4.5.1.1
359
+ # scope: https://tools.ietf.org/html/rfc4511#section-4.5.1.2
360
+ filter = args [ :filter ] || Net ::LDAP ::Filter . eq ( "objectClass" , "*" )
361
+ base = args [ :base ]
362
+ scope = args [ :scope ] || Net ::LDAP ::SearchScope_WholeSubtree
363
+
364
+ # attr handling
365
+ # attrs: https://tools.ietf.org/html/rfc4511#section-4.5.1.8
366
+ # attrs_only: https://tools.ietf.org/html/rfc4511#section-4.5.1.6
367
+ attrs = Array ( args [ :attributes ] )
368
+ attrs_only = args [ :attributes_only ] == true
369
+
370
+ # references
371
+ # refs: https://tools.ietf.org/html/rfc4511#section-4.5.3
372
+ # deref: https://tools.ietf.org/html/rfc4511#section-4.5.1.3
373
+ refs = args [ :return_referrals ] == true
374
+ deref = args [ :deref ] || Net ::LDAP ::DerefAliases_Never
375
+
376
+ # limiting, paging, sorting
377
+ # size: https://tools.ietf.org/html/rfc4511#section-4.5.1.4
378
+ size = args [ :size ] . to_i
379
+ paged = args [ :paged_searches_supported ]
380
+ sort = args . fetch ( :sort_controls , false )
381
+
382
+ # arg validation
383
+ raise Net ::LDAP ::LdapError , "search base is required" unless base
384
+ raise Net ::LDAP ::LdapError , "invalid search-size" unless size >= 0
366
385
raise Net ::LDAP ::LdapError , "invalid search scope" unless Net ::LDAP ::SearchScopes . include? ( scope )
386
+ raise Net ::LDAP ::LdapError , "invalid alias dereferencing value" unless Net ::LDAP ::DerefAliasesArray . include? ( deref )
367
387
368
- sort_control = encode_sort_controls ( args . fetch ( :sort_controls ) { false } )
369
-
370
- deref = args [ :deref ] || Net ::LDAP ::DerefAliases_Never
371
- raise Net ::LDAP ::LdapError . new ( "invalid alias dereferencing value" ) unless Net ::LDAP ::DerefAliasesArray . include? ( deref )
372
-
388
+ # arg transforms
389
+ filter = Net ::LDAP ::Filter . construct ( filter ) if filter . is_a? ( String )
390
+ ber_attrs = attrs . map { |attr | attr . to_s . to_ber }
391
+ ber_sort = encode_sort_controls ( sort )
373
392
374
393
# An interesting value for the size limit would be close to A/D's
375
394
# built-in page limit of 1000 records, but openLDAP newer than version
@@ -398,36 +417,36 @@ def search(args = {})
398
417
message_id = next_msgid
399
418
400
419
instrument "search.net_ldap_connection" ,
401
- : message_id => message_id ,
402
- : filter => search_filter ,
403
- : base => search_base ,
404
- : scope => scope ,
405
- : limit => sizelimit ,
406
- : sort => sort_control ,
407
- : referrals => return_referrals ,
408
- : deref => deref ,
409
- : attributes => search_attributes do |payload |
420
+ message_id : message_id ,
421
+ filter : filter ,
422
+ base : base ,
423
+ scope : scope ,
424
+ limit : size ,
425
+ sort : sort ,
426
+ referrals : refs ,
427
+ deref : deref ,
428
+ attributes : attrs do |payload |
410
429
loop do
411
430
# should collect this into a private helper to clarify the structure
412
431
query_limit = 0
413
- if sizelimit > 0
414
- if paged_searches_supported
415
- query_limit = ( ( ( sizelimit - n_results ) < 126 ) ? ( sizelimit -
432
+ if size > 0
433
+ if paged
434
+ query_limit = ( ( ( size - n_results ) < 126 ) ? ( size -
416
435
n_results ) : 0 )
417
436
else
418
- query_limit = sizelimit
437
+ query_limit = size
419
438
end
420
439
end
421
440
422
441
request = [
423
- search_base . to_ber ,
442
+ base . to_ber ,
424
443
scope . to_ber_enumerated ,
425
444
deref . to_ber_enumerated ,
426
445
query_limit . to_ber , # size limit
427
446
0 . to_ber ,
428
- attributes_only . to_ber ,
429
- search_filter . to_ber ,
430
- search_attributes . to_ber_sequence
447
+ attrs_only . to_ber ,
448
+ filter . to_ber ,
449
+ ber_attrs . to_ber_sequence
431
450
] . to_ber_appsequence ( 3 )
432
451
433
452
# rfc2696_cookie sometimes contains binary data from Microsoft Active Directory
@@ -441,8 +460,8 @@ def search(args = {})
441
460
# Criticality MUST be false to interoperate with normal LDAPs.
442
461
false . to_ber ,
443
462
rfc2696_cookie . map { |v | v . to_ber } . to_ber_sequence . to_s . to_ber
444
- ] . to_ber_sequence if paged_searches_supported
445
- controls << sort_control if sort_control
463
+ ] . to_ber_sequence if paged
464
+ controls << ber_sort if ber_sort
446
465
controls = controls . empty? ? nil : controls . to_ber_contextspecific ( 0 )
447
466
448
467
write ( request , controls , message_id )
@@ -456,7 +475,7 @@ def search(args = {})
456
475
n_results += 1
457
476
yield pdu . search_entry if block_given?
458
477
when Net ::LDAP ::PDU ::SearchResultReferral
459
- if return_referrals
478
+ if refs
460
479
if block_given?
461
480
se = Net ::LDAP ::Entry . new
462
481
se [ :search_referrals ] = ( pdu . search_referrals || [ ] )
@@ -466,7 +485,7 @@ def search(args = {})
466
485
when Net ::LDAP ::PDU ::SearchResult
467
486
result_pdu = pdu
468
487
controls = pdu . result_controls
469
- if return_referrals && pdu . result_code == 10
488
+ if refs && pdu . result_code == 10
470
489
if block_given?
471
490
se = Net ::LDAP ::Entry . new
472
491
se [ :search_referrals ] = ( pdu . search_referrals || [ ] )
0 commit comments