activeldap 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. data/CHANGES +61 -0
  2. data/README +8 -1
  3. data/Rakefile +4 -1
  4. data/benchmark/bench-al.rb +12 -2
  5. data/examples/al-admin/app/controllers/account_controller.rb +4 -3
  6. data/examples/al-admin/app/controllers/application.rb +5 -2
  7. data/examples/al-admin/app/controllers/directory_controller.rb +3 -1
  8. data/examples/al-admin/app/controllers/users_controller.rb +19 -4
  9. data/examples/al-admin/app/controllers/welcome_controller.rb +4 -2
  10. data/examples/al-admin/app/helpers/application_helper.rb +7 -1
  11. data/examples/al-admin/app/helpers/url_helper.rb +4 -0
  12. data/examples/al-admin/app/models/ldap_user.rb +4 -0
  13. data/examples/al-admin/app/views/_entry/{_attributes_information.rhtml → _attributes_information.html.erb} +0 -0
  14. data/examples/al-admin/app/views/_entry/{_entry.rhtml → _entry.html.erb} +0 -0
  15. data/examples/al-admin/app/views/_schema/{_aliases.rhtml → _aliases.html.erb} +0 -0
  16. data/examples/al-admin/app/views/_switcher/{_after.rhtml → _after.html.erb} +0 -0
  17. data/examples/al-admin/app/views/_switcher/{_before.rhtml → _before.html.erb} +0 -0
  18. data/examples/al-admin/app/views/account/{login.rhtml → login.html.erb} +0 -0
  19. data/examples/al-admin/app/views/account/{sign_up.rhtml → sign_up.html.erb} +0 -0
  20. data/examples/al-admin/app/views/attributes/{_attributes.rhtml → _attributes.html.erb} +0 -0
  21. data/examples/al-admin/app/views/attributes/{_detail.rhtml → _detail.html.erb} +0 -0
  22. data/examples/al-admin/app/views/attributes/{index.rhtml → index.html.erb} +0 -0
  23. data/examples/al-admin/app/views/attributes/{show.rhtml → show.html.erb} +0 -0
  24. data/examples/al-admin/app/views/directory/{_tree.rhtml → _tree.html.erb} +0 -0
  25. data/examples/al-admin/app/views/directory/{_tree_view_js.rhtml → _tree_view_js.html.erb} +4 -5
  26. data/examples/al-admin/app/views/directory/{index.rhtml → index.html.erb} +0 -0
  27. data/examples/al-admin/app/views/directory/{populate.rhtml → populate.html.erb} +0 -0
  28. data/examples/al-admin/app/views/layouts/{_footer.rhtml → _footer.html.erb} +0 -0
  29. data/examples/al-admin/app/views/layouts/{_header_menu.rhtml → _header_menu.html.erb} +0 -0
  30. data/examples/al-admin/app/views/layouts/{_main_menu.rhtml → _main_menu.html.erb} +0 -0
  31. data/examples/al-admin/app/views/layouts/{application.rhtml → application.html.erb} +3 -2
  32. data/examples/al-admin/app/views/object_classes/{_attributes.rhtml → _attributes.html.erb} +0 -0
  33. data/examples/al-admin/app/views/object_classes/{_object_classes.rhtml → _object_classes.html.erb} +0 -0
  34. data/examples/al-admin/app/views/object_classes/{index.rhtml → index.html.erb} +0 -0
  35. data/examples/al-admin/app/views/object_classes/{show.rhtml → show.html.erb} +0 -0
  36. data/examples/al-admin/app/views/syntaxes/{_detail.rhtml → _detail.html.erb} +0 -0
  37. data/examples/al-admin/app/views/syntaxes/{_syntaxes.rhtml → _syntaxes.html.erb} +0 -0
  38. data/examples/al-admin/app/views/syntaxes/{index.rhtml → index.html.erb} +0 -0
  39. data/examples/al-admin/app/views/syntaxes/{show.rhtml → show.html.erb} +0 -0
  40. data/examples/al-admin/app/views/users/{_attributes_update_form.rhtml → _attributes_update_form.html.erb} +0 -0
  41. data/examples/al-admin/app/views/users/{_form.rhtml → _form.html.erb} +0 -0
  42. data/examples/al-admin/app/views/users/{_object_classes_update_form.rhtml → _object_classes_update_form.html.erb} +7 -1
  43. data/examples/al-admin/app/views/users/{_password_change_form.rhtml → _password_change_form.html.erb} +0 -0
  44. data/examples/al-admin/app/views/users/{edit.rhtml → edit.html.erb} +0 -0
  45. data/examples/al-admin/app/views/users/{index.rhtml → index.html.erb} +0 -0
  46. data/examples/al-admin/app/views/users/{show.rhtml → show.html.erb} +0 -0
  47. data/examples/al-admin/app/views/welcome/{index.rhtml → index.html.erb} +0 -0
  48. data/examples/al-admin/config/boot.rb +96 -32
  49. data/examples/al-admin/config/environment.rb +30 -36
  50. data/examples/al-admin/config/environments/development.rb +2 -5
  51. data/examples/al-admin/config/environments/production.rb +1 -0
  52. data/examples/al-admin/config/environments/test.rb +4 -1
  53. data/examples/al-admin/config/initializers/exception_notifier.rb +2 -0
  54. data/examples/al-admin/config/initializers/gettext.rb +1 -0
  55. data/examples/al-admin/config/initializers/inflections.rb +10 -0
  56. data/examples/al-admin/config/initializers/mime_types.rb +5 -0
  57. data/examples/al-admin/config/initializers/ralative_url_support.rb +1 -0
  58. data/examples/al-admin/config/routes.rb +24 -12
  59. data/examples/al-admin/lib/authenticated_system.rb +1 -1
  60. data/examples/al-admin/lib/tasks/gettext.rake +1 -1
  61. data/examples/al-admin/po/en/al-admin.po +102 -100
  62. data/examples/al-admin/po/ja/al-admin.po +112 -110
  63. data/examples/al-admin/po/nl/al-admin.po +117 -110
  64. data/examples/al-admin/public/javascripts/controls.js +484 -354
  65. data/examples/al-admin/public/javascripts/dragdrop.js +88 -58
  66. data/examples/al-admin/public/javascripts/effects.js +396 -364
  67. data/examples/al-admin/public/javascripts/prototype.js +2817 -1107
  68. data/examples/al-admin/public/stylesheets/base.css +5 -0
  69. data/examples/al-admin/script/performance/request +3 -0
  70. data/lib/active_ldap.rb +13 -10
  71. data/lib/active_ldap/adapter/base.rb +159 -43
  72. data/lib/active_ldap/adapter/jndi.rb +175 -0
  73. data/lib/active_ldap/adapter/jndi_connection.rb +180 -0
  74. data/lib/active_ldap/adapter/ldap.rb +91 -46
  75. data/lib/active_ldap/adapter/ldap_ext.rb +19 -5
  76. data/lib/active_ldap/adapter/net_ldap.rb +52 -44
  77. data/lib/active_ldap/association/has_many_wrap.rb +1 -1
  78. data/lib/active_ldap/attributes.rb +20 -95
  79. data/lib/active_ldap/base.rb +195 -186
  80. data/lib/active_ldap/callbacks.rb +33 -0
  81. data/lib/active_ldap/command.rb +3 -3
  82. data/lib/active_ldap/connection.rb +21 -3
  83. data/lib/active_ldap/distinguished_name.rb +18 -11
  84. data/lib/active_ldap/entry_attribute.rb +78 -0
  85. data/lib/active_ldap/human_readable.rb +20 -0
  86. data/lib/active_ldap/ldif.rb +860 -10
  87. data/lib/active_ldap/object_class.rb +6 -4
  88. data/lib/active_ldap/operations.rb +129 -22
  89. data/lib/active_ldap/schema.rb +118 -9
  90. data/lib/active_ldap/schema/syntaxes.rb +33 -16
  91. data/lib/active_ldap/validations.rb +74 -65
  92. data/po/en/active-ldap.po +378 -768
  93. data/po/ja/active-ldap.po +935 -868
  94. data/rails/plugin/active_ldap/init.rb +40 -2
  95. data/test/al-test-utils.rb +78 -58
  96. data/test/command.rb +51 -1
  97. data/test/test-unit-ext/priority.rb +29 -6
  98. data/test/test_adapter.rb +21 -2
  99. data/test/test_attributes.rb +13 -0
  100. data/test/test_base.rb +51 -1
  101. data/test/test_connection.rb +2 -1
  102. data/test/test_connection_per_class.rb +55 -1
  103. data/test/test_connection_per_dn.rb +29 -1
  104. data/test/test_find.rb +73 -0
  105. data/test/test_ldif.rb +1829 -15
  106. data/test/test_load.rb +126 -0
  107. data/test/test_object_class.rb +23 -5
  108. data/test/test_schema.rb +28 -0
  109. data/test/test_syntax.rb +22 -11
  110. data/test/test_user.rb +16 -25
  111. data/test/test_useradd-binary.rb +1 -1
  112. data/test/test_usermod-binary-add-time.rb +1 -1
  113. data/test/test_usermod-binary-add.rb +1 -1
  114. data/test/test_validation.rb +100 -22
  115. metadata +77 -71
  116. data/data/locale/en/LC_MESSAGES/active-ldap.mo +0 -0
  117. data/data/locale/ja/LC_MESSAGES/active-ldap.mo +0 -0
  118. data/examples/al-admin/app/views/layouts/_flash_box.rhtml +0 -4
  119. data/examples/al-admin/public/stylesheets/common.css +0 -2
  120. data/examples/al-admin/script/breakpointer +0 -3
@@ -0,0 +1,180 @@
1
+ require 'java'
2
+
3
+ java.util.Enumeration.module_eval do
4
+ include Enumerable
5
+
6
+ def each
7
+ while has_more_elements
8
+ yield(next_element)
9
+ end
10
+ end
11
+ end
12
+
13
+ module ActiveLdap
14
+ module Adapter
15
+ class JndiConnection
16
+ HashTable = java.util.Hashtable
17
+ naming = javax.naming
18
+ directory = naming.directory
19
+ ldap = naming.ldap
20
+ InitialDirContext = directory.InitialDirContext
21
+ InitialLdapContext = ldap.InitialLdapContext
22
+ SearchControls = directory.SearchControls
23
+ ModificationItem = directory.ModificationItem
24
+ BasicAttributes = directory.BasicAttributes
25
+ Context = naming.Context
26
+ StartTlsRequest = ldap.StartTlsRequest
27
+ Control = ldap.Control
28
+
29
+ NamingException = naming.NamingException
30
+ NameNotFoundException = naming.NameNotFoundException
31
+
32
+ class ModifyRecord
33
+ directory = javax.naming.directory
34
+ DirContext = directory.DirContext
35
+ BasicAttribute = directory.BasicAttribute
36
+
37
+ ADD_ATTRIBUTE = DirContext::ADD_ATTRIBUTE
38
+ REPLACE_ATTRIBUTE = DirContext::REPLACE_ATTRIBUTE
39
+ REMOVE_ATTRIBUTE = DirContext::REMOVE_ATTRIBUTE
40
+
41
+ attr_reader :type, :name, :values
42
+ def initialize(type, name, values, binary)
43
+ @type = self.class.const_get("#{type.to_s.upcase}_ATTRIBUTE")
44
+ @name = name
45
+ @values = values
46
+ @binary = binary
47
+ end
48
+
49
+ def binary?
50
+ @binary
51
+ end
52
+
53
+ def to_java_modification_item
54
+ ModificationItem.new(@type, to_java_attribute)
55
+ end
56
+
57
+ def to_java_attribute
58
+ attribute = BasicAttribute.new(@name)
59
+ values = @values
60
+ values = values.collect(&:to_java_bytes) if binary?
61
+ values.each do |value|
62
+ attribute.add(value)
63
+ end
64
+ attribute
65
+ end
66
+ end
67
+
68
+ def initialize(host, port, method)
69
+ @host = host
70
+ @port = port
71
+ @method = method
72
+ @context = nil
73
+ @tls = nil
74
+ end
75
+
76
+ def unbind
77
+ @tls.close if @tls
78
+ @tls = nil
79
+ @context.close if @context
80
+ @context = nil
81
+ end
82
+
83
+ def bound?
84
+ not @context.nil?
85
+ end
86
+
87
+ def sasl_bind(bind_dn, mechanism, quiet)
88
+ setup_context(bind_dn, password, mechanism)
89
+ bound?
90
+ end
91
+
92
+ def simple_bind(bind_dn, password)
93
+ setup_context(bind_dn, password, "simple")
94
+ bound?
95
+ end
96
+
97
+ def bind_as_anonymous
98
+ setup_context(nil, nil, "none")
99
+ bound?
100
+ end
101
+
102
+ def search(base, scope, filter, attrs, limit, callback, &block)
103
+ controls = SearchControls.new
104
+ controls.search_scope = scope
105
+
106
+ if attrs && !attrs.empty?
107
+ controls.returning_attributes = attrs.to_java(:string)
108
+ end
109
+
110
+ i = 0
111
+ @context.search(base, filter, controls).each do |result|
112
+ i += 1
113
+ attributes = {}
114
+ result.attributes.get_all.each do |attribute|
115
+ attributes[attribute.get_id] = attribute.get_all.collect do |value|
116
+ value.is_a?(String) ? value : String.from_java_bytes(value)
117
+ end
118
+ end
119
+ callback.call([result.name_in_namespace, attributes], block)
120
+ break if limit and limit <= i
121
+ end
122
+ end
123
+
124
+ def add(dn, records)
125
+ attributes = BasicAttributes.new
126
+ records.each do |record|
127
+ attributes.put(record.to_java_attribute)
128
+ end
129
+ @context.create_subcontext(dn, attributes)
130
+ end
131
+
132
+ def modify(dn, records)
133
+ items = records.collect(&:to_java_modification_item)
134
+ @context.modify_attributes(dn, items.to_java(ModificationItem))
135
+ end
136
+
137
+ def modify_rdn(dn, new_rdn, delete_old_rdn)
138
+ # should use mutex
139
+ delete_rdn_key = "java.naming.ldap.deleteRDN"
140
+ @context.add_to_environment(delete_rdn_key, delete_old_rdn.to_s)
141
+ @context.rename(dn, new_rdn)
142
+ ensure
143
+ @context.remove_from_environment(delete_rdn_key)
144
+ end
145
+
146
+ def delete(dn)
147
+ @context.destroy_subcontext(dn)
148
+ end
149
+
150
+ private
151
+ def setup_context(bind_dn, password, authentication)
152
+ unbind
153
+ environment = {
154
+ Context::INITIAL_CONTEXT_FACTORY => "com.sun.jndi.ldap.LdapCtxFactory",
155
+ Context::PROVIDER_URL => ldap_uri,
156
+ }
157
+ environment = HashTable.new(environment)
158
+ context = InitialLdapContext.new(environment, nil)
159
+ if @method == :start_tls
160
+ @tls = context.extended_operation(StartTlsRequest.new)
161
+ @tls.negotiate
162
+ end
163
+ context.add_to_environment(Context::SECURITY_AUTHENTICATION,
164
+ authentication)
165
+ if bind_dn
166
+ context.add_to_environment(Context::SECURITY_PRINCIPAL, bind_dn)
167
+ end
168
+ if password
169
+ context.add_to_environment(Context::SECURITY_CREDENTIALS, password)
170
+ end
171
+ @context = context
172
+ end
173
+
174
+ def ldap_uri
175
+ protocol = @method == :ssl ? "ldaps" : "ldap"
176
+ "#{protocol}://#{@host}:#{@port}/"
177
+ end
178
+ end
179
+ end
180
+ end
@@ -13,19 +13,37 @@ module ActiveLdap
13
13
 
14
14
  class Ldap < Base
15
15
  module Method
16
- class SSL
16
+ class Base
17
+ def ssl?
18
+ false
19
+ end
20
+
21
+ def start_tls?
22
+ false
23
+ end
24
+ end
25
+
26
+ class SSL < Base
17
27
  def connect(host, port)
18
28
  LDAP::SSLConn.new(host, port, false)
19
29
  end
30
+
31
+ def ssl?
32
+ true
33
+ end
20
34
  end
21
35
 
22
- class TLS
36
+ class TLS < Base
23
37
  def connect(host, port)
24
38
  LDAP::SSLConn.new(host, port, true)
25
39
  end
40
+
41
+ def start_tls?
42
+ true
43
+ end
26
44
  end
27
45
 
28
- class Plain
46
+ class Plain < Base
29
47
  def connect(host, port)
30
48
  LDAP::Conn.new(host, port)
31
49
  end
@@ -34,7 +52,11 @@ module ActiveLdap
34
52
 
35
53
  def connect(options={})
36
54
  super do |host, port, method|
37
- method.connect(host, port)
55
+ uri = construct_uri(host, port, method.ssl?)
56
+ with_start_tls = method.start_tls?
57
+ info = {:uri => uri, :with_start_tls => with_start_tls}
58
+ [log("connect", info) {method.connect(host, port)},
59
+ uri, with_start_tls]
38
60
  end
39
61
  end
40
62
 
@@ -53,7 +75,7 @@ module ActiveLdap
53
75
 
54
76
  def bind_as_anonymous(options={})
55
77
  super do
56
- execute(:bind)
78
+ execute(:bind, :name => "bind: anonymous")
57
79
  true
58
80
  end
59
81
  end
@@ -66,7 +88,11 @@ module ActiveLdap
66
88
  super(options) do |base, scope, filter, attrs, limit, callback|
67
89
  begin
68
90
  i = 0
69
- execute(:search, base, scope, filter, attrs) do |entry|
91
+ info = {
92
+ :base => base, :scope => scope_name(scope),
93
+ :filter => filter, :attributes => attrs,
94
+ }
95
+ execute(:search, info, base, scope, filter, attrs) do |entry|
70
96
  i += 1
71
97
  attributes = {}
72
98
  entry.attrs.each do |attr|
@@ -76,6 +102,11 @@ module ActiveLdap
76
102
  break if limit and limit <= i
77
103
  end
78
104
  rescue RuntimeError
105
+ begin
106
+ @connection.assert_error_code
107
+ rescue LDAP::ServerDown
108
+ raise ConnectionError, $!.message
109
+ end
79
110
  if $!.message == "no result returned by search"
80
111
  @logger.debug do
81
112
  args = [filter, attrs.inspect]
@@ -88,37 +119,55 @@ module ActiveLdap
88
119
  end
89
120
  end
90
121
 
91
- def to_ldif(dn, attributes)
92
- ldif = LDAP::LDIF.to_ldif("dn", [dn.dup])
93
- attributes.sort_by do |key, value|
94
- key
95
- end.each do |key, values|
96
- ldif << LDAP::LDIF.to_ldif(key, values)
97
- end
98
- ldif
99
- end
100
-
101
- def load(ldifs, options={})
102
- super do |ldif|
103
- LDAP::LDIF.parse_entry(ldif).send(@connection)
104
- end
105
- end
106
-
107
122
  def delete(targets, options={})
108
123
  super do |target|
109
- execute(:delete, target)
124
+ controls = options[:controls]
125
+ info = {:dn => target}
126
+ if controls
127
+ info.merge!(:name => :delete, :controls => controls)
128
+ execute(:delete_ext, info,
129
+ target, controls, [])
130
+ else
131
+ execute(:delete, info, target)
132
+ end
110
133
  end
111
134
  end
112
135
 
113
136
  def add(dn, entries, options={})
114
137
  super do |dn, entries|
115
- execute(:add, dn, parse_entries(entries))
138
+ controls = options[:controls]
139
+ attributes = parse_entries(entries)
140
+ info = {:dn => dn, :attributes => entries}
141
+ if controls
142
+ info.merge!(:name => :add, :controls => controls)
143
+ execute(:add_ext, info, dn, attributes, controls, [])
144
+ else
145
+ execute(:add, info, dn, attributes)
146
+ end
116
147
  end
117
148
  end
118
149
 
119
150
  def modify(dn, entries, options={})
120
151
  super do |dn, entries|
121
- execute(:modify, dn, parse_entries(entries))
152
+ controls = options[:controls]
153
+ attributes = parse_entries(entries)
154
+ info = {:dn => dn, :attributes => entries}
155
+ if controls
156
+ info.merge!(:name => :modify, :controls => controls)
157
+ execute(:modify_ext, info, dn, attributes, controls, [])
158
+ else
159
+ execute(:modify, info, dn, attributes)
160
+ end
161
+ end
162
+ end
163
+
164
+ def modify_rdn(dn, new_rdn, delete_old_rdn, new_superior, options={})
165
+ super do |dn, new_rdn, delete_old_rdn, new_superior|
166
+ info = {
167
+ :name => "modify: RDN",
168
+ :dn => dn, :new_rdn => new_rdn, :delete_old_rdn => delete_old_rdn
169
+ }
170
+ execute(:modrdn, info, dn, new_rdn, delete_old_rdn)
122
171
  end
123
172
  end
124
173
 
@@ -129,31 +178,16 @@ module ActiveLdap
129
178
  end
130
179
  end
131
180
 
132
- def root_dse(attributes, options={})
133
- sec = options[:sec] || 0
134
- usec = options[:usec] || 0
135
- @connection.root_dse(attributes, sec, usec)
136
- end
137
-
138
- def execute(method, *args, &block)
181
+ def execute(method, info=nil, *args, &block)
139
182
  begin
140
- @connection.send(method, *args, &block)
183
+ name = (info || {}).delete(:name) || method
184
+ log(name, info) {@connection.send(method, *args, &block)}
141
185
  rescue LDAP::ResultError
142
186
  @connection.assert_error_code
143
187
  raise $!.message
144
188
  end
145
189
  end
146
190
 
147
- def with_timeout(try_reconnect=true, options={}, &block)
148
- begin
149
- super
150
- rescue LDAP::ServerDown => e
151
- @logger.error {_("LDAP server is down: %s") % e.message}
152
- retry if try_reconnect and reconnect(options)
153
- raise ConnectionError.new(e.message)
154
- end
155
- end
156
-
157
191
  def ensure_method(method)
158
192
  Method.constants.each do |name|
159
193
  if method.to_s.downcase == name.downcase
@@ -183,6 +217,14 @@ module ActiveLdap
183
217
  value
184
218
  end
185
219
 
220
+ def scope_name(scope)
221
+ {
222
+ LDAP::LDAP_SCOPE_BASE => :base,
223
+ LDAP::LDAP_SCOPE_SUBTREE => :sub,
224
+ LDAP::LDAP_SCOPE_ONELEVEL => :one,
225
+ }[scope]
226
+ end
227
+
186
228
  def sasl_bind(bind_dn, options={})
187
229
  super do |bind_dn, mechanism, quiet|
188
230
  begin
@@ -192,7 +234,10 @@ module ActiveLdap
192
234
  if need_credential_sasl_mechanism?(mechanism)
193
235
  args << password(bind_dn, options)
194
236
  end
195
- execute(:sasl_bind, *args)
237
+ info = {
238
+ :name => "bind: SASL", :dn => bind_dn, :mechanism => mechanism
239
+ }
240
+ execute(:sasl_bind, info, *args)
196
241
  ensure
197
242
  @connection.sasl_quiet = sasl_quiet
198
243
  end
@@ -201,7 +246,7 @@ module ActiveLdap
201
246
 
202
247
  def simple_bind(bind_dn, options={})
203
248
  super do |bind_dn, passwd|
204
- execute(:bind, bind_dn, passwd)
249
+ execute(:bind, {:dn => bind_dn}, bind_dn, passwd)
205
250
  end
206
251
  end
207
252
 
@@ -220,7 +265,7 @@ module ActiveLdap
220
265
 
221
266
  def ensure_mod_type(type)
222
267
  case type
223
- when :replace, :add
268
+ when :replace, :add, :delete
224
269
  LDAP.const_get("LDAP_MOD_#{type.to_s.upcase}")
225
270
  else
226
271
  raise ArgumentError, _("unknown type: %s") % type
@@ -3,6 +3,10 @@ require 'ldap/ldif'
3
3
  require 'ldap/schema'
4
4
 
5
5
  module LDAP
6
+ unless const_defined?(:LDAP_OPT_ERROR_NUMBER)
7
+ LDAP_OPT_ERROR_NUMBER = 0x0031
8
+ end
9
+
6
10
  class Mod
7
11
  unless instance_method(:to_s).arity.zero?
8
12
  alias_method :original_to_s, :to_s
@@ -47,12 +51,18 @@ module LDAP
47
51
 
48
52
  class Conn
49
53
  def failed?
50
- not err.zero?
54
+ not error_code.zero?
55
+ end
56
+
57
+ def error_code
58
+ code = err
59
+ code = get_option(LDAP_OPT_ERROR_NUMBER) if code.zero?
60
+ code
51
61
  end
52
62
 
53
63
  def error_message
54
64
  if failed?
55
- LDAP.err2string(err)
65
+ LDAP.err2string(error_code)
56
66
  else
57
67
  nil
58
68
  end
@@ -60,10 +70,14 @@ module LDAP
60
70
 
61
71
  def assert_error_code
62
72
  return unless failed?
63
- klass = ActiveLdap::LdapError::ERRORS[err]
64
- klass ||= IMPLEMENT_SPECIFIC_ERRORS[err]
73
+ code = error_code
74
+ klass = ActiveLdap::LdapError::ERRORS[code]
75
+ klass ||= IMPLEMENT_SPECIFIC_ERRORS[code]
76
+ if klass.nil? and error_message == "Can't contact LDAP server"
77
+ klass = LDAP::ServerDown
78
+ end
65
79
  klass ||= ActiveLdap::LdapError
66
- raise klass, LDAP.err2string(err)
80
+ raise klass, LDAP.err2string(code)
67
81
  end
68
82
  end
69
83
  end