Skip to content

Commit 7438a2a

Browse files
Denis KnaufDenis Knauf
authored andcommitted
One LdapError-class => Specific errors for every exception.
1 parent 8a18267 commit 7438a2a

File tree

5 files changed

+62
-35
lines changed

5 files changed

+62
-35
lines changed

lib/net/ldap.rb

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,33 @@ class Net::LDAP
244244
VERSION = "0.4.0"
245245

246246
class LdapError < StandardError; end
247+
class AlreadyOpenedError < LdapError; end
248+
class SocketError < LdapError; end
249+
class ConnectionRefusedError < LdapError; end
250+
class NoOpenSSLError < LdapError; end
251+
class NoStartTLSResultError < LdapError; end
252+
class StartTLSError < LdapError; end
253+
class EncryptionUnsupportedError < LdapError; end
254+
class EncMethodUnsupportedError < LdapError; end
255+
class AuthMethodUnsupportedError < LdapError; end
256+
class BindingInformationInvalidError < LdapError; end
257+
class NoBindResultError < LdapError; end
258+
class SASLChallengeOverflowError < LdapError; end
259+
class SearchSizeInvalidError < LdapError; end
260+
class SearchScopeInvalidError < LdapError; end
261+
class ResponseTypeInvalidError < LdapError; end
262+
class ResponseMissingOrInvalidError < LdapError; end
263+
class EmptyDNError < LdapError; end
264+
class HashTypeUnsupportedError < LdapError; end
265+
class OperatorError < LdapError; end
266+
class SubstringFilterError < LdapError; end
267+
class SearchFilterError < LdapError; end
268+
class BERInvalidError < LdapError; end
269+
class SearchFilterTypeUnknownError < LdapError; end
270+
class BadAttributeError < LdapError; end
271+
class FilterTypeUnknownError < LdapError; end
272+
class FilterSyntaxInvalidError < LdapError; end
273+
class EntryOverflowError < LdapError; end
247274

248275
SearchScope_BaseObject = 0
249276
SearchScope_SingleLevel = 1
@@ -563,7 +590,7 @@ def open
563590
# anything with the bind results. We then pass self to the caller's
564591
# block, where he will execute his LDAP operations. Of course they will
565592
# all generate auth failures if the bind was unsuccessful.
566-
raise Net::LDAP::LdapError, "Open already in progress" if @open_connection
593+
raise Net::LDAP::AlreadyOpenedError, "Open already in progress" if @open_connection
567594

568595
begin
569596
@open_connection = Net::LDAP::Connection.new(:host => @host,
@@ -1134,9 +1161,9 @@ def initialize(server)
11341161
begin
11351162
@conn = TCPSocket.new(server[:host], server[:port])
11361163
rescue SocketError
1137-
raise Net::LDAP::LdapError, "No such address or other socket error."
1164+
raise Net::LDAP::SocketError, "No such address or other socket error."
11381165
rescue Errno::ECONNREFUSED
1139-
raise Net::LDAP::LdapError, "Server #{server[:host]} refused connection on port #{server[:port]}."
1166+
raise Net::LDAP::ConnectionRefusedError, "Server #{server[:host]} refused connection on port #{server[:port]}."
11401167
end
11411168

11421169
if server[:encryption]
@@ -1153,7 +1180,7 @@ def getbyte
11531180
end
11541181

11551182
def self.wrap_with_ssl(io)
1156-
raise Net::LDAP::LdapError, "OpenSSL is unavailable" unless Net::LDAP::HasOpenSSL
1183+
raise Net::LDAP::NoOpenSSLError, "OpenSSL is unavailable" unless Net::LDAP::HasOpenSSL
11571184
ctx = OpenSSL::SSL::SSLContext.new
11581185
conn = OpenSSL::SSL::SSLSocket.new(io, ctx)
11591186
conn.connect
@@ -1202,16 +1229,16 @@ def setup_encryption(args)
12021229
request_pkt = [msgid, request].to_ber_sequence
12031230
@conn.write request_pkt
12041231
be = @conn.read_ber(Net::LDAP::AsnSyntax)
1205-
raise Net::LDAP::LdapError, "no start_tls result" if be.nil?
1232+
raise Net::LDAP::NoStartTLSResultError, "no start_tls result" if be.nil?
12061233
pdu = Net::LDAP::PDU.new(be)
1207-
raise Net::LDAP::LdapError, "no start_tls result" if pdu.nil?
1234+
raise Net::LDAP::NoStartTLSResultError, "no start_tls result" if pdu.nil?
12081235
if pdu.result_code.zero?
12091236
@conn = self.class.wrap_with_ssl(@conn)
12101237
else
1211-
raise Net::LDAP::LdapError, "start_tls failed: #{pdu.result_code}"
1238+
raise Net::LDAP::StartTLSError, "start_tls failed: #{pdu.result_code}"
12121239
end
12131240
else
1214-
raise Net::LDAP::LdapError, "unsupported encryption method #{args[:method]}"
1241+
raise Net::LDAP::EncryptionUnsupportedError, "unsupported encryption method #{args[:method]}"
12151242
end
12161243
end
12171244

@@ -1239,7 +1266,7 @@ def bind(auth)
12391266
elsif meth == :gss_spnego
12401267
bind_gss_spnego(auth)
12411268
else
1242-
raise Net::LDAP::LdapError, "Unsupported auth method (#{meth})"
1269+
raise Net::LDAP::AuthMethodUnsupportedError, "Unsupported auth method (#{meth})"
12431270
end
12441271
end
12451272

@@ -1254,15 +1281,15 @@ def bind_simple(auth)
12541281
["", ""]
12551282
end
12561283

1257-
raise Net::LDAP::LdapError, "Invalid binding information" unless (user && psw)
1284+
raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (user && psw)
12581285

12591286
msgid = next_msgid.to_ber
12601287
request = [LdapVersion.to_ber, user.to_ber,
12611288
psw.to_ber_contextspecific(0)].to_ber_appsequence(0)
12621289
request_pkt = [msgid, request].to_ber_sequence
12631290
@conn.write request_pkt
12641291

1265-
(be = @conn.read_ber(Net::LDAP::AsnSyntax) and pdu = Net::LDAP::PDU.new(be)) or raise Net::LDAP::LdapError, "no bind result"
1292+
(be = @conn.read_ber(Net::LDAP::AsnSyntax) and pdu = Net::LDAP::PDU.new(be)) or raise Net::LDAP::NoBindResultError, "no bind result"
12661293

12671294
pdu
12681295
end
@@ -1291,7 +1318,7 @@ def bind_simple(auth)
12911318
def bind_sasl(auth)
12921319
mech, cred, chall = auth[:mechanism], auth[:initial_credential],
12931320
auth[:challenge_response]
1294-
raise Net::LDAP::LdapError, "Invalid binding information" unless (mech && cred && chall)
1321+
raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (mech && cred && chall)
12951322

12961323
n = 0
12971324
loop {
@@ -1301,9 +1328,9 @@ def bind_sasl(auth)
13011328
request_pkt = [msgid, request].to_ber_sequence
13021329
@conn.write request_pkt
13031330

1304-
(be = @conn.read_ber(Net::LDAP::AsnSyntax) and pdu = Net::LDAP::PDU.new(be)) or raise Net::LDAP::LdapError, "no bind result"
1331+
(be = @conn.read_ber(Net::LDAP::AsnSyntax) and pdu = Net::LDAP::PDU.new(be)) or raise Net::LDAP::NoBindResultError, "no bind result"
13051332
return pdu unless pdu.result_code == 14 # saslBindInProgress
1306-
raise Net::LDAP::LdapError, "sasl-challenge overflow" if ((n += 1) > MaxSaslChallenges)
1333+
raise Net::LDAP::SASLChallengeOverflowError, "sasl-challenge overflow" if ((n += 1) > MaxSaslChallenges)
13071334

13081335
cred = chall.call(pdu.result_server_sasl_creds)
13091336
}
@@ -1327,7 +1354,7 @@ def bind_gss_spnego(auth)
13271354
require 'ntlm'
13281355

13291356
user, psw = [auth[:username] || auth[:dn], auth[:password]]
1330-
raise Net::LDAP::LdapError, "Invalid binding information" unless (user && psw)
1357+
raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (user && psw)
13311358

13321359
nego = proc { |challenge|
13331360
t2_msg = NTLM::Message.parse(challenge)
@@ -1389,12 +1416,12 @@ def search(args = {})
13891416
search_attributes = ((args && args[:attributes]) || []).map { |attr| attr.to_s.to_ber}
13901417
return_referrals = args && args[:return_referrals] == true
13911418
sizelimit = (args && args[:size].to_i) || 0
1392-
raise Net::LDAP::LdapError, "invalid search-size" unless sizelimit >= 0
1419+
raise Net::LDAP::SearchSizeInvalidError, "invalid search-size" unless sizelimit >= 0
13931420
paged_searches_supported = (args && args[:paged_searches_supported])
13941421

13951422
attributes_only = (args and args[:attributes_only] == true)
13961423
scope = args[:scope] || Net::LDAP::SearchScope_WholeSubtree
1397-
raise Net::LDAP::LdapError, "invalid search scope" unless Net::LDAP::SearchScopes.include?(scope)
1424+
raise Net::LDAP::SearchScopeInvalidError, "invalid search scope" unless Net::LDAP::SearchScopes.include?(scope)
13981425

13991426
sort_control = encode_sort_controls(args.fetch(:sort_controls){ false })
14001427
# An interesting value for the size limit would be close to A/D's
@@ -1490,7 +1517,7 @@ def search(args = {})
14901517
end
14911518
break
14921519
else
1493-
raise Net::LDAP::LdapError, "invalid response-type in search: #{pdu.app_tag}"
1520+
raise Net::LDAP::ResponseTypeInvalidError, "invalid response-type in search: #{pdu.app_tag}"
14941521
end
14951522
end
14961523

@@ -1563,7 +1590,7 @@ def modify(args)
15631590
pkt = [ next_msgid.to_ber, request ].to_ber_sequence
15641591
@conn.write pkt
15651592

1566-
(be = @conn.read_ber(Net::LDAP::AsnSyntax)) && (pdu = Net::LDAP::PDU.new(be)) && (pdu.app_tag == 7) or raise Net::LDAP::LdapError, "response missing or invalid"
1593+
(be = @conn.read_ber(Net::LDAP::AsnSyntax)) && (pdu = Net::LDAP::PDU.new(be)) && (pdu.app_tag == 7) or raise Net::LDAP::ResponseMissingOrInvalidError, "response missing or invalid"
15671594

15681595
pdu
15691596
end
@@ -1576,7 +1603,7 @@ def modify(args)
15761603
# to the error message and the matched-DN returned by the server.
15771604
#++
15781605
def add(args)
1579-
add_dn = args[:dn] or raise Net::LDAP::LdapError, "Unable to add empty DN"
1606+
add_dn = args[:dn] or raise Net::LDAP::EmptyDNError, "Unable to add empty DN"
15801607
add_attrs = []
15811608
a = args[:attributes] and a.each { |k, v|
15821609
add_attrs << [ k.to_s.to_ber, Array(v).map { |m| m.to_ber}.to_ber_set ].to_ber_sequence
@@ -1589,7 +1616,7 @@ def add(args)
15891616
(be = @conn.read_ber(Net::LDAP::AsnSyntax)) &&
15901617
(pdu = Net::LDAP::PDU.new(be)) &&
15911618
(pdu.app_tag == 9) or
1592-
raise Net::LDAP::LdapError, "response missing or invalid"
1619+
raise Net::LDAP::ResponseMissingOrInvalidError, "response missing or invalid"
15931620

15941621
pdu
15951622
end
@@ -1611,7 +1638,7 @@ def rename(args)
16111638

16121639
(be = @conn.read_ber(Net::LDAP::AsnSyntax)) &&
16131640
(pdu = Net::LDAP::PDU.new( be )) && (pdu.app_tag == 13) or
1614-
raise Net::LDAP::LdapError.new( "response missing or invalid" )
1641+
raise Net::LDAP::ResponseMissingOrInvalidError.new( "response missing or invalid" )
16151642

16161643
pdu
16171644
end
@@ -1626,7 +1653,7 @@ def delete(args)
16261653
pkt = [next_msgid.to_ber, request, controls].compact.to_ber_sequence
16271654
@conn.write pkt
16281655

1629-
(be = @conn.read_ber(Net::LDAP::AsnSyntax)) && (pdu = Net::LDAP::PDU.new(be)) && (pdu.app_tag == 11) or raise Net::LDAP::LdapError, "response missing or invalid"
1656+
(be = @conn.read_ber(Net::LDAP::AsnSyntax)) && (pdu = Net::LDAP::PDU.new(be)) && (pdu.app_tag == 11) or raise Net::LDAP::ResponseMissingOrInvalidError, "response missing or invalid"
16301657

16311658
pdu
16321659
end

lib/net/ldap/entry.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def from_single_ldif_string(ldif)
7171

7272
return nil if ds.empty?
7373

74-
raise Net::LDAP::LdapError, "Too many LDIF entries" unless ds.size == 1
74+
raise Net::LDAP::EntryOverflowError, "Too many LDIF entries" unless ds.size == 1
7575

7676
entry = ds.to_entries.first
7777

lib/net/ldap/filter.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class Net::LDAP::Filter
2727

2828
def initialize(op, left, right) #:nodoc:
2929
unless FilterTypes.include?(op)
30-
raise Net::LDAP::LdapError, "Invalid or unsupported operator #{op.inspect} in LDAP Filter."
30+
raise Net::LDAP::OperatorError, "Invalid or unsupported operator #{op.inspect} in LDAP Filter."
3131
end
3232
@op = op
3333
@left = left
@@ -290,7 +290,7 @@ def parse_ber(ber)
290290
ber.last.each { |b|
291291
case b.ber_identifier
292292
when 0x80 # context-specific primitive 0, SubstringFilter "initial"
293-
raise Net::LDAP::LdapError, "Unrecognized substring filter; bad initial value." if str.length > 0
293+
raise Net::LDAP::SubstringFilterError, "Unrecognized substring filter; bad initial value." if str.length > 0
294294
str += b
295295
when 0x81 # context-specific primitive 0, SubstringFilter "any"
296296
str += "*#{b}"
@@ -309,7 +309,7 @@ def parse_ber(ber)
309309
# call to_s to get rid of the BER-identifiedness of the incoming string.
310310
present?(ber.to_s)
311311
when 0xa9 # context-specific constructed 9, "extensible comparison"
312-
raise Net::LDAP::LdapError, "Invalid extensible search filter, should be at least two elements" if ber.size<2
312+
raise Net::LDAP::SearchFilterError, "Invalid extensible search filter, should be at least two elements" if ber.size<2
313313

314314
# Reassembles the extensible filter parts
315315
# (["sn", "2.4.6.8.10", "Barbara Jones", '1'])
@@ -330,7 +330,7 @@ def parse_ber(ber)
330330

331331
ex(attribute, value)
332332
else
333-
raise Net::LDAP::LdapError, "Invalid BER tag-value (#{ber.ber_identifier}) in search filter."
333+
raise Net::LDAP::BERInvalidError, "Invalid BER tag-value (#{ber.ber_identifier}) in search filter."
334334
end
335335
end
336336

@@ -357,7 +357,7 @@ def parse_ldap_filter(obj)
357357
when 0xa3 # equalityMatch. context-specific constructed 3.
358358
eq(obj[0], obj[1])
359359
else
360-
raise Net::LDAP::LdapError, "Unknown LDAP search-filter type: #{obj.ber_identifier}"
360+
raise Net::LDAP::SearchFilterTypeUnknownError, "Unknown LDAP search-filter type: #{obj.ber_identifier}"
361361
end
362362
end
363363
end
@@ -534,7 +534,7 @@ def to_ber
534534
seq = []
535535

536536
unless @left =~ /^([-;\w]*)(:dn)?(:(\w+|[.\w]+))?$/
537-
raise Net::LDAP::LdapError, "Bad attribute #{@left}"
537+
raise Net::LDAP::BadAttributeError, "Bad attribute #{@left}"
538538
end
539539
type, dn, rule = $1, $2, $4
540540

@@ -641,7 +641,7 @@ def match(entry)
641641
l = entry[@left] and l = Array(l) and l.index(@right)
642642
end
643643
else
644-
raise Net::LDAP::LdapError, "Unknown filter type in match: #{@op}"
644+
raise Net::LDAP::FilterTypeUnknownError, "Unknown filter type in match: #{@op}"
645645
end
646646
end
647647

@@ -674,7 +674,7 @@ def parse(ldap_filter_string)
674674
def initialize(str)
675675
require 'strscan' # Don't load strscan until we need it.
676676
@filter = parse(StringScanner.new(str))
677-
raise Net::LDAP::LdapError, "Invalid filter syntax." unless @filter
677+
raise Net::LDAP::FilterSyntaxInvalidError, "Invalid filter syntax." unless @filter
678678
end
679679

680680
##

lib/net/ldap/password.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def generate(type, str)
2929
srand; salt = (rand * 1000).to_i.to_s
3030
attribute_value = '{SSHA}' + Base64.encode64(Digest::SHA1.digest(str + salt) + salt).chomp!
3131
else
32-
raise Net::LDAP::LdapError, "Unsupported password-hash type (#{type})"
32+
raise Net::LDAP::HashTypeUnsupportedError, "Unsupported password-hash type (#{type})"
3333
end
3434
return attribute_value
3535
end

test/test_filter.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ def test_bug_7534_rfc2254
99
end
1010

1111
def test_invalid_filter_string
12-
assert_raises(Net::LDAP::LdapError) { Filter.from_rfc2254("") }
12+
assert_raises(Net::LDAP::FilterSyntaxInvalidError) { Filter.from_rfc2254("") }
1313
end
1414

1515
def test_invalid_filter
16-
assert_raises(Net::LDAP::LdapError) {
16+
assert_raises(Net::LDAP::OperatorError) {
1717
# This test exists to prove that our constructor blocks unknown filter
1818
# types. All filters must be constructed using helpers.
1919
Filter.__send__(:new, :xx, nil, nil)

0 commit comments

Comments
 (0)