@@ -1488,108 +1488,124 @@ def search(args = {})
14881488 result_pdu = nil
14891489 n_results = 0
14901490
1491- loop {
1492- # should collect this into a private helper to clarify the structure
1493- query_limit = 0
1494- if sizelimit > 0
1495- if paged_searches_supported
1496- query_limit = ( ( ( sizelimit - n_results ) < 126 ) ? ( sizelimit -
1497- n_results ) : 0 )
1498- else
1499- query_limit = sizelimit
1491+ instrument "search.net_ldap_connection" ,
1492+ :filter => search_filter ,
1493+ :base => search_base ,
1494+ :scope => scope ,
1495+ :limit => sizelimit ,
1496+ :sort => sort_control ,
1497+ :referrals => return_referrals ,
1498+ :deref => deref ,
1499+ :attributes => search_attributes do |payload |
1500+ loop do
1501+ # should collect this into a private helper to clarify the structure
1502+ query_limit = 0
1503+ if sizelimit > 0
1504+ if paged_searches_supported
1505+ query_limit = ( ( ( sizelimit - n_results ) < 126 ) ? ( sizelimit -
1506+ n_results ) : 0 )
1507+ else
1508+ query_limit = sizelimit
1509+ end
15001510 end
1501- end
15021511
1503- request = [
1504- search_base . to_ber ,
1505- scope . to_ber_enumerated ,
1506- deref . to_ber_enumerated ,
1507- query_limit . to_ber , # size limit
1508- 0 . to_ber ,
1509- attributes_only . to_ber ,
1510- search_filter . to_ber ,
1511- search_attributes . to_ber_sequence
1512- ] . to_ber_appsequence ( 3 )
1513-
1514- # rfc2696_cookie sometimes contains binary data from Microsoft Active Directory
1515- # this breaks when calling to_ber. (Can't force binary data to UTF-8)
1516- # we have to disable paging (even though server supports it) to get around this...
1517-
1518- controls = [ ]
1519- controls <<
1520- [
1521- Net ::LDAP ::LDAPControls ::PAGED_RESULTS . to_ber ,
1522- # Criticality MUST be false to interoperate with normal LDAPs.
1523- false . to_ber ,
1524- rfc2696_cookie . map { |v | v . to_ber } . to_ber_sequence . to_s . to_ber
1525- ] . to_ber_sequence if paged_searches_supported
1526- controls << sort_control if sort_control
1527- controls = controls . empty? ? nil : controls . to_ber_contextspecific ( 0 )
1528-
1529- pkt = [ next_msgid . to_ber , request , controls ] . compact . to_ber_sequence
1530- write pkt
1531-
1532- result_pdu = nil
1533- controls = [ ]
1534-
1535- while ( be = read ) && ( pdu = Net ::LDAP ::PDU . new ( be ) )
1536- case pdu . app_tag
1537- when 4 # search-data
1538- n_results += 1
1539- yield pdu . search_entry if block_given?
1540- when 19 # search-referral
1541- if return_referrals
1542- if block_given?
1543- se = Net ::LDAP ::Entry . new
1544- se [ :search_referrals ] = ( pdu . search_referrals || [ ] )
1545- yield se
1512+ request = [
1513+ search_base . to_ber ,
1514+ scope . to_ber_enumerated ,
1515+ deref . to_ber_enumerated ,
1516+ query_limit . to_ber , # size limit
1517+ 0 . to_ber ,
1518+ attributes_only . to_ber ,
1519+ search_filter . to_ber ,
1520+ search_attributes . to_ber_sequence
1521+ ] . to_ber_appsequence ( 3 )
1522+
1523+ # rfc2696_cookie sometimes contains binary data from Microsoft Active Directory
1524+ # this breaks when calling to_ber. (Can't force binary data to UTF-8)
1525+ # we have to disable paging (even though server supports it) to get around this...
1526+
1527+ controls = [ ]
1528+ controls <<
1529+ [
1530+ Net ::LDAP ::LDAPControls ::PAGED_RESULTS . to_ber ,
1531+ # Criticality MUST be false to interoperate with normal LDAPs.
1532+ false . to_ber ,
1533+ rfc2696_cookie . map { |v | v . to_ber } . to_ber_sequence . to_s . to_ber
1534+ ] . to_ber_sequence if paged_searches_supported
1535+ controls << sort_control if sort_control
1536+ controls = controls . empty? ? nil : controls . to_ber_contextspecific ( 0 )
1537+
1538+ pkt = [ next_msgid . to_ber , request , controls ] . compact . to_ber_sequence
1539+ write pkt
1540+
1541+ result_pdu = nil
1542+ controls = [ ]
1543+
1544+ while ( be = read ) && ( pdu = Net ::LDAP ::PDU . new ( be ) )
1545+ case pdu . app_tag
1546+ when 4 # search-data
1547+ n_results += 1
1548+ yield pdu . search_entry if block_given?
1549+ when 19 # search-referral
1550+ if return_referrals
1551+ if block_given?
1552+ se = Net ::LDAP ::Entry . new
1553+ se [ :search_referrals ] = ( pdu . search_referrals || [ ] )
1554+ yield se
1555+ end
15461556 end
1547- end
1548- when 5 # search-result
1549- result_pdu = pdu
1550- controls = pdu . result_controls
1551- if return_referrals && pdu . result_code == 10
1552- if block_given?
1553- se = Net :: LDAP :: Entry . new
1554- se [ :search_referrals ] = ( pdu . search_referrals || [ ] )
1555- yield se
1557+ when 5 # search-result
1558+ result_pdu = pdu
1559+ controls = pdu . result_controls
1560+ if return_referrals && pdu . result_code == 10
1561+ if block_given?
1562+ se = Net :: LDAP :: Entry . new
1563+ se [ :search_referrals ] = ( pdu . search_referrals || [ ] )
1564+ yield se
1565+ end
15561566 end
1567+ break
1568+ else
1569+ raise Net ::LDAP ::LdapError , "invalid response-type in search: #{ pdu . app_tag } "
15571570 end
1558- break
1559- else
1560- raise Net ::LDAP ::LdapError , "invalid response-type in search: #{ pdu . app_tag } "
15611571 end
1562- end
15631572
1564- # When we get here, we have seen a type-5 response. If there is no
1565- # error AND there is an RFC-2696 cookie, then query again for the next
1566- # page of results. If not, we're done. Don't screw this up or we'll
1567- # break every search we do.
1568- #
1569- # Noticed 02Sep06, look at the read_ber call in this loop, shouldn't
1570- # that have a parameter of AsnSyntax? Does this just accidentally
1571- # work? According to RFC-2696, the value expected in this position is
1572- # of type OCTET STRING, covered in the default syntax supported by
1573- # read_ber, so I guess we're ok.
1574- more_pages = false
1575- if result_pdu . result_code == 0 and controls
1576- controls . each do |c |
1577- if c . oid == Net ::LDAP ::LDAPControls ::PAGED_RESULTS
1578- # just in case some bogus server sends us more than 1 of these.
1579- more_pages = false
1580- if c . value and c . value . length > 0
1581- cookie = c . value . read_ber [ 1 ]
1582- if cookie and cookie . length > 0
1583- rfc2696_cookie [ 1 ] = cookie
1584- more_pages = true
1573+ # count number of pages of results
1574+ payload [ :page_count ] ||= 0
1575+ payload [ :page_count ] += 1
1576+
1577+ # When we get here, we have seen a type-5 response. If there is no
1578+ # error AND there is an RFC-2696 cookie, then query again for the next
1579+ # page of results. If not, we're done. Don't screw this up or we'll
1580+ # break every search we do.
1581+ #
1582+ # Noticed 02Sep06, look at the read_ber call in this loop, shouldn't
1583+ # that have a parameter of AsnSyntax? Does this just accidentally
1584+ # work? According to RFC-2696, the value expected in this position is
1585+ # of type OCTET STRING, covered in the default syntax supported by
1586+ # read_ber, so I guess we're ok.
1587+ more_pages = false
1588+ if result_pdu . result_code == 0 and controls
1589+ controls . each do |c |
1590+ if c . oid == Net ::LDAP ::LDAPControls ::PAGED_RESULTS
1591+ # just in case some bogus server sends us more than 1 of these.
1592+ more_pages = false
1593+ if c . value and c . value . length > 0
1594+ cookie = c . value . read_ber [ 1 ]
1595+ if cookie and cookie . length > 0
1596+ rfc2696_cookie [ 1 ] = cookie
1597+ more_pages = true
1598+ end
15851599 end
15861600 end
15871601 end
15881602 end
1589- end
15901603
1591- break unless more_pages
1592- } # loop
1604+ break unless more_pages
1605+ end # loop
1606+
1607+ payload [ :result_count ] = n_results
1608+ end # instrument
15931609
15941610 result_pdu || OpenStruct . new ( :status => :failure , :result_code => 1 , :message => "Invalid search" )
15951611 end
0 commit comments