Class ActiveLdap::Adapter::Base
In: lib/active_ldap/adapter/jndi.rb
lib/active_ldap/adapter/net_ldap.rb
lib/active_ldap/adapter/ldap.rb
lib/active_ldap/adapter/base.rb
Parent: Object
Error AttributeAssignmentError AdapterNotSpecified OperationNotPermitted RequiredObjectClassMissed ConnectionError RequiredAttributeMissed LdifInvalid DistinguishedNameNotSetError EntryNotFound LdapError SaveError StrongAuthenticationRequired NotImplemented AdapterNotFound TimeoutError AuthenticationError AttributeValueInvalid EntryNotSaved DistinguishedNameInputInvalid EntryAlreadyExist ObjectClassError UnknownAttribute EntryInvalid DeleteError ConfigurationError ConnectionNotSetup DistinguishedNameInvalid Schema\n[lib/active_ldap/schema.rb\nlib/active_ldap/schema/syntaxes.rb] Base DistinguishedName Reloadable::Deprecated Reloadable::Subclasses Enumerable Ldif Collection EntryAttribute StandardError Children HasManyWrap HasMany BelongsToMany Proxy BelongsTo Normalizable Common Find LDIF Delete Update ActiveRecord::Callbacks GetText Parser Base\n[lib/active_ldap/adapter/base.rb\nlib/active_ldap/adapter/jndi.rb\nlib/active_ldap/adapter/ldap.rb\nlib/active_ldap/adapter/net_ldap.rb] Jndi Ldap NetLdap GetTextSupport ActiveRecord::Validations Xml JndiConnection lib/active_ldap/distinguished_name.rb lib/active_ldap/base.rb lib/active_ldap/xml.rb lib/active_ldap/schema.rb lib/active_ldap/entry_attribute.rb lib/active_ldap/ldif.rb lib/active_ldap/ldap_error.rb Compatible ClassMethods Associations LdapBenchmarking ActionController Populate lib/active_ldap/association/has_many_wrap.rb lib/active_ldap/association/children.rb lib/active_ldap/association/collection.rb lib/active_ldap/association/proxy.rb lib/active_ldap/association/belongs_to_many.rb lib/active_ldap/association/belongs_to.rb lib/active_ldap/association/has_many.rb HasManyUtils Association ClassMethods Tree Acts Command ClassMethods Normalizable Attributes Update Common ModifyNameRecordLoadable AddOperationModifiable DeleteOperationModifiable ReplaceOperationModifiable ModifyRecordLoadable DeleteRecordLoadable AddRecordLoadable ContentRecordLoadable LDIF Delete Find Operations GetTextSupport Escape ClassMethods Configuration ClassMethods ObjectClass ClassMethods Callbacks lib/active_ldap/get_text/parser.rb GetText lib/active_ldap/adapter/jndi_connection.rb lib/active_ldap/adapter/net_ldap.rb lib/active_ldap/adapter/ldap.rb lib/active_ldap/adapter/base.rb lib/active_ldap/adapter/jndi.rb Adapter Validations GetTextFallback Helper ClassMethods HumanReadable Salt UserPassword ClassMethods Connection ActiveLdap dot/m_46_0.png

Methods

Included Modules

GetTextSupport

Constants

VALID_ADAPTER_CONFIGURATION_KEYS = [:host, :port, :method, :timeout, :retry_on_timeout, :retry_limit, :retry_wait, :bind_dn, :password, :password_block, :try_sasl, :sasl_mechanisms, :sasl_quiet, :allow_anonymous, :store_password, :scope, :sasl_options]
LOGICAL_OPERATORS = [:and, :or, :not, :&, :|]

Attributes

runtime  [R] 

Public Class methods

[Source]

    # File lib/active_ldap/adapter/jndi.rb, line 7
 7:         def jndi_connection(options)
 8:           require 'active_ldap/adapter/jndi_connection'
 9:           Jndi.new(options)
10:         end

[Source]

    # File lib/active_ldap/adapter/ldap.rb, line 7
 7:         def ldap_connection(options)
 8:           require 'active_ldap/adapter/ldap_ext'
 9:           Ldap.new(options)
10:         end

[Source]

    # File lib/active_ldap/adapter/net_ldap.rb, line 9
 9:         def net_ldap_connection(options)
10:           require 'active_ldap/adapter/net_ldap_ext'
11:           NetLdap.new(options)
12:         end

[Source]

    # File lib/active_ldap/adapter/base.rb, line 23
23:       def initialize(configuration={})
24:         @runtime = 0
25:         @connection = nil
26:         @disconnected = false
27:         @bound = false
28:         @bind_tried = false
29:         @entry_attributes = {}
30:         @configuration = configuration.dup
31:         @logger = @configuration.delete(:logger)
32:         @configuration.assert_valid_keys(VALID_ADAPTER_CONFIGURATION_KEYS)
33:         VALID_ADAPTER_CONFIGURATION_KEYS.each do |name|
34:           instance_variable_set("@#{name}", configuration[name])
35:         end
36:       end

Public Instance methods

[Source]

     # File lib/active_ldap/adapter/base.rb, line 202
202:       def add(dn, entries, options={})
203:         dn = ensure_dn_string(dn)
204:         begin
205:           operation(options) do
206:             yield(dn, entries)
207:           end
208:         rescue LdapError::NoSuchObject
209:           raise EntryNotFound, _("No such entry: %s") % dn
210:         rescue LdapError::InvalidDnSyntax
211:           raise DistinguishedNameInvalid.new(dn)
212:         rescue LdapError::AlreadyExists
213:           raise EntryAlreadyExist, _("%s: %s") % [$!.message, dn]
214:         rescue LdapError::StrongAuthRequired
215:           raise StrongAuthenticationRequired, _("%s: %s") % [$!.message, dn]
216:         rescue LdapError::ObjectClassViolation
217:           raise RequiredAttributeMissed, _("%s: %s") % [$!.message, dn]
218:         rescue LdapError::UnwillingToPerform
219:           raise OperationNotPermitted, _("%s: %s") % [$!.message, dn]
220:         end
221:       end

[Source]

    # File lib/active_ldap/adapter/base.rb, line 67
67:       def bind(options={})
68:         @bind_tried = true
69: 
70:         bind_dn = ensure_dn_string(options[:bind_dn] || @bind_dn)
71:         try_sasl = options.has_key?(:try_sasl) ? options[:try_sasl] : @try_sasl
72:         if options.has_key?(:allow_anonymous)
73:           allow_anonymous = options[:allow_anonymous]
74:         else
75:           allow_anonymous = @allow_anonymous
76:         end
77:         options = options.merge(:allow_anonymous => allow_anonymous)
78: 
79:         # Rough bind loop:
80:         # Attempt 1: SASL if available
81:         # Attempt 2: SIMPLE with credentials if password block
82:         # Attempt 3: SIMPLE ANONYMOUS if 1 and 2 fail (or pwblock returns '')
83:         if try_sasl and sasl_bind(bind_dn, options)
84:           @logger.info {_('Bound to %s by SASL as %s') % [target, bind_dn]}
85:         elsif simple_bind(bind_dn, options)
86:           @logger.info {_('Bound to %s by simple as %s') % [target, bind_dn]}
87:         elsif allow_anonymous and bind_as_anonymous(options)
88:           @logger.info {_('Bound to %s as anonymous') % target}
89:         else
90:           message = yield if block_given?
91:           message ||= _('All authentication methods for %s exhausted.') % target
92:           raise AuthenticationError, message
93:         end
94: 
95:         @bound = true
96:         @bound
97:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 104
104:       def bind_as_anonymous(options={})
105:         yield
106:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 112
112:       def bound?
113:         connecting? and @bound
114:       end

[Source]

    # File lib/active_ldap/adapter/base.rb, line 43
43:       def connect(options={})
44:         host = options[:host] || @host
45:         method = options[:method] || @method || :plain
46:         port = options[:port] || @port || ensure_port(method)
47:         method = ensure_method(method)
48:         @disconnected = false
49:         @bound = false
50:         @bind_tried = false
51:         @connection, @uri, @with_start_tls = yield(host, port, method)
52:         prepare_connection(options)
53:         bind(options)
54:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 108
108:       def connecting?
109:         !@connection.nil? and !@disconnected
110:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 183
183:       def delete(targets, options={})
184:         targets = [targets] unless targets.is_a?(Array)
185:         return if targets.empty?
186:         begin
187:           operation(options) do
188:             targets.each do |target|
189:               target = ensure_dn_string(target)
190:               begin
191:                 yield(target)
192:               rescue LdapError::UnwillingToPerform, LdapError::InsufficientAccess
193:                 raise OperationNotPermitted, _("%s: %s") % [$!.message, target]
194:               end
195:             end
196:           end
197:         rescue LdapError::NoSuchObject
198:           raise EntryNotFound, _("No such entry: %s") % target
199:         end
200:       end

[Source]

    # File lib/active_ldap/adapter/base.rb, line 56
56:       def disconnect!(options={})
57:         unbind(options)
58:         @connection = @uri = @with_start_tls = nil
59:         @disconnected = true
60:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 146
146:       def entry_attribute(object_classes)
147:         @entry_attributes[object_classes.uniq.sort] ||=
148:           EntryAttribute.new(schema, object_classes)
149:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 247
247:       def log_info(name, runtime_in_seconds, info=nil)
248:         return unless @logger
249:         return unless @logger.debug?
250:         message = "LDAP: #{name} (#{'%.1f' % (runtime_in_seconds * 1000)}ms)"
251:         @logger.debug(format_log_entry(message, info))
252:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 223
223:       def modify(dn, entries, options={})
224:         dn = ensure_dn_string(dn)
225:         begin
226:           operation(options) do
227:             begin
228:               yield(dn, entries)
229:             rescue LdapError::UnwillingToPerform, LdapError::InsufficientAccess
230:               raise OperationNotPermitted, _("%s: %s") % [$!.message, target]
231:             end
232:           end
233:         rescue LdapError::UndefinedType
234:           raise
235:         rescue LdapError::ObjectClassViolation
236:           raise RequiredAttributeMissed, _("%s: %s") % [$!.message, dn]
237:         end
238:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 240
240:       def modify_rdn(dn, new_rdn, delete_old_rdn, new_superior, options={})
241:         dn = ensure_dn_string(dn)
242:         operation(options) do
243:           yield(dn, new_rdn, delete_old_rdn, new_superior)
244:         end
245:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 142
142:       def naming_contexts
143:         root_dse_values('namingContexts')
144:       end

[Source]

    # File lib/active_ldap/adapter/base.rb, line 62
62:       def rebind(options={})
63:         unbind(options) if bound?
64:         connect(options)
65:       end

[Source]

    # File lib/active_ldap/adapter/base.rb, line 38
38:       def reset_runtime
39:         runtime, @runtime = @runtime, 0
40:         runtime
41:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 116
116:       def schema(options={})
117:         @schema ||= operation(options) do
118:           base = options[:base]
119:           attrs = options[:attributes]
120: 
121:           attrs ||= [
122:             'objectClasses',
123:             'attributeTypes',
124:             'matchingRules',
125:             'matchingRuleUse',
126:             'dITStructureRules',
127:             'dITContentRules',
128:             'nameForms',
129:             'ldapSyntaxes',
130:             #'extendedAttributeInfo', # if we need RANGE-LOWER/UPPER.
131:           ]
132:           base ||= root_dse_values('subschemaSubentry', options)[0]
133:           base ||= 'cn=schema'
134:           dn, attributes = search(:base => base,
135:                                   :scope => :base,
136:                                   :filter => '(objectClass=subschema)',
137:                                   :attributes => attrs).first
138:           Schema.new(attributes)
139:         end
140:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 151
151:       def search(options={})
152:         filter = parse_filter(options[:filter]) || 'objectClass=*'
153:         attrs = options[:attributes] || []
154:         scope = ensure_scope(options[:scope] || @scope)
155:         base = options[:base]
156:         limit = options[:limit] || 0
157:         limit = nil if limit <= 0
158: 
159:         attrs = attrs.to_a # just in case
160: 
161:         values = []
162:         callback = Proc.new do |value, block|
163:           value = block.call(value) if block
164:           values << value
165:         end
166: 
167:         base = ensure_dn_string(base)
168:         begin
169:           operation(options) do
170:             yield(base, scope, filter, attrs, limit, callback)
171:           end
172:         rescue LdapError::NoSuchObject, LdapError::InvalidDnSyntax
173:           # Do nothing on failure
174:           @logger.info do
175:             args = [$!.class, $!.message, filter, attrs.inspect]
176:             _("Ignore error %s(%s): filter %s: attributes: %s") % args
177:           end
178:         end
179: 
180:         values
181:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 99
 99:       def unbind(options={})
100:         yield if @connection and (@bind_tried or bound?)
101:         @bind_tried = @bound = false
102:       end

Private Instance methods

[Source]

     # File lib/active_ldap/adapter/base.rb, line 556
556:       def assert_filter_logical_operator(operator)
557:         return if operator.nil?
558:         unless filter_logical_operator?(operator)
559:           raise ArgumentError,
560:                 _("invalid logical operator: %s: available operators: %s") %
561:                   [operator.inspect, LOGICAL_OPERATORS.inspect]
562:         end
563:       end

Determine if we have exceed the retry limit or not. True is reconnecting is allowed - False if not.

[Source]

     # File lib/active_ldap/adapter/base.rb, line 617
617:       def can_reconnect?(options={})
618:         retry_limit = options[:retry_limit] || @retry_limit
619:         reconnect_attempts = options[:reconnect_attempts] || 0
620: 
621:         retry_limit < 0 or reconnect_attempts <= retry_limit
622:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 535
535:       def collection?(object)
536:         !object.is_a?(String) and object.respond_to?(:each)
537:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 468
468:       def construct_component(key, value, operator=nil)
469:         value, options = extract_filter_value_options(value)
470:         comparison_operator = options[:operator] || "="
471:         if collection?(value)
472:           return nil if value.empty?
473:           operator, value = normalize_array_filter(value, operator)
474:           values = []
475:           value.each do |val|
476:             if collection?(val)
477:               values.concat(val.collect {|v| [key, comparison_operator, v]})
478:             else
479:               values << [key, comparison_operator, val]
480:             end
481:           end
482:           values[0] = values[0][1] if filter_logical_operator?(values[0][1])
483:           parse_filter(values, operator)
484:         else
485:           [
486:            "(",
487:            escape_filter_key(key),
488:            comparison_operator,
489:            escape_filter_value(value, options),
490:            ")"
491:           ].join
492:         end
493:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 444
444:       def construct_components(components, operator)
445:         components.collect do |component|
446:           if component.is_a?(Array)
447:             if filter_logical_operator?(component[0])
448:               parse_filter(component)
449:             elsif component.size == 2
450:               key, value = component
451:               if value.is_a?(Hash)
452:                 parse_filter(value, key)
453:               else
454:                 construct_component(key, value, operator)
455:               end
456:             else
457:               construct_component(component[0], component[1..-1], operator)
458:             end
459:           elsif component.is_a?(Symbol)
460:             assert_filter_logical_operator(component)
461:             nil
462:           else
463:             parse_filter(component, operator)
464:           end
465:         end
466:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 520
520:       def construct_filter(components, operator=nil)
521:         operator = normalize_filter_logical_operator(operator)
522:         components = components.compact
523:         case components.size
524:         when 0
525:           nil
526:         when 1
527:           filter = components[0]
528:           filter = "(!#{filter})" if operator == :not
529:           filter
530:         else
531:           "(#{operator == :and ? '&' : '|'}#{components.join})"
532:         end
533:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 642
642:       def construct_uri(host, port, ssl)
643:         protocol = ssl ? "ldaps" : "ldap"
644:         URI.parse("#{protocol}://#{host}:#{port}").to_s
645:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 694
694:       def ensure_dn_string(dn)
695:         if dn.is_a?(DN)
696:           dn.to_s
697:         else
698:           dn
699:         end
700:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 255
255:       def ensure_port(method)
256:         if method == :ssl
257:           URI::LDAPS::DEFAULT_PORT
258:         else
259:           URI::LDAP::DEFAULT_PORT
260:         end
261:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 495
495:       def escape_filter_key(key)
496:         escape_filter_value(key.to_s)
497:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 499
499:       def escape_filter_value(value, options={})
500:         case value
501:         when Numeric, DN
502:           value = value.to_s
503:         when Time
504:           value = Schema::GeneralizedTime.new.normalize_value(value)
505:         end
506:         value.gsub(/(?:[()\\\0]|\*\*?)/) do |s|
507:           if s == "*"
508:             s
509:           else
510:             s = "*" if s == "**"
511:             if s.respond_to?(:getbyte)
512:               "\\%02X" % s.getbyte(0)
513:             else
514:               "\\%02X" % s[0]
515:             end
516:           end
517:         end
518:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 425
425:       def extract_filter_value_options(value)
426:         options = {}
427:         if value.is_a?(Array)
428:           case value[0]
429:           when Hash
430:             options = value[0]
431:             value = value[1]
432:           when "=", "~=", "<=", ">="
433:             options[:operator] = value[0]
434:             if value.size > 2
435:               value = value[1..-1]
436:             else
437:               value = value[1]
438:             end
439:           end
440:         end
441:         [value, options]
442:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 540
540:       def filter_logical_operator?(operator)
541:         LOGICAL_OPERATORS.include?(operator)
542:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 674
674:       def format_log_entry(message, info=nil)
675:         if ActiveLdap::Base.colorize_logging
676:           if @@row_even
677:             message_color, dump_color = "4;36;1", "0;1"
678:           else
679:             @@row_even = true
680:             message_color, dump_color = "4;35;1", "0"
681:           end
682:           @@row_even = !@@row_even
683: 
684:           log_entry = "  \e[#{message_color}m#{message}\e[0m"
685:           log_entry << ": \e[#{dump_color}m#{info.inspect}\e[0m" if info
686:           log_entry
687:         else
688:           log_entry = message
689:           log_entry += ": #{info.inspect}" if info
690:           log_entry
691:         end
692:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 656
656:       def log(name, info=nil)
657:         if block_given?
658:           result = nil
659:           seconds = Benchmark.realtime {result = yield}
660:           @runtime += seconds
661:           log_info(name, seconds, info)
662:           result
663:         else
664:           log_info(name, 0, info)
665:           nil
666:         end
667:       rescue Exception
668:         log_info("#{name}: FAILED", 0,
669:                  (info || {}).merge(:error => $!.class.name,
670:                                     :error_message => $!.message))
671:         raise
672:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 288
288:       def need_credential_sasl_mechanism?(mechanism)
289:         not %(GSSAPI EXTERNAL ANONYMOUS).include?(mechanism)
290:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 414
414:       def normalize_array_filter(filter, operator=nil)
415:         filter_operator, *components = filter
416:         if filter_logical_operator?(filter_operator)
417:           operator = filter_operator
418:         else
419:           components.unshift(filter_operator)
420:           components = [components] unless filter_operator.is_a?(Array)
421:         end
422:         [operator, components]
423:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 544
544:       def normalize_filter_logical_operator(operator)
545:         assert_filter_logical_operator(operator)
546:         case (operator || :and)
547:         when :and, :&
548:           :and
549:         when :or, :|
550:           :or
551:         else
552:           :not
553:         end
554:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 266
266:       def operation(options)
267:         retried = false
268:         options = options.dup
269:         options[:try_reconnect] = true unless options.has_key?(:try_reconnect)
270:         try_reconnect = false
271:         begin
272:           reconnect_if_need(options)
273:           try_reconnect = options[:try_reconnect]
274:           with_timeout(try_reconnect, options) do
275:             yield
276:           end
277:         rescue ConnectionError
278:           if try_reconnect and !retried
279:             retried = true
280:             @disconnected = true
281:             retry
282:           else
283:             raise
284:           end
285:         end
286:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 381
381:       def parse_filter(filter, operator=nil)
382:         return nil if filter.nil?
383:         if !filter.is_a?(String) and !filter.respond_to?(:collect)
384:           filter = filter.to_s
385:         end
386: 
387:         case filter
388:         when String
389:           parse_filter_string(filter)
390:         when Hash
391:           components = filter.sort_by {|k, v| k.to_s}.collect do |key, value|
392:             construct_component(key, value, operator)
393:           end
394:           construct_filter(components, operator)
395:         else
396:           operator, components = normalize_array_filter(filter, operator)
397:           components = construct_components(components, operator)
398:           construct_filter(components, operator)
399:         end
400:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 402
402:       def parse_filter_string(filter)
403:         if /\A\s*\z/.match(filter)
404:           nil
405:         else
406:           if filter[0, 1] == "("
407:             filter
408:           else
409:             "(#{filter})"
410:           end
411:         end
412:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 292
292:       def password(bind_dn, options={})
293:         passwd = options[:password] || @password
294:         return passwd if passwd
295: 
296:         password_block = options[:password_block] || @password_block
297:         # TODO: Give a warning to reconnect users with password clearing
298:         # Get the passphrase for the first time, or anew if we aren't storing
299:         if password_block.respond_to?(:call)
300:           passwd = password_block.call(bind_dn)
301:         else
302:           @logger.error {_('password_block not nil or Proc object. Ignoring.')}
303:           return nil
304:         end
305: 
306:         # Store the password for quick reference later
307:         if options.has_key?(:store_password)
308:           store_password = options[:store_password]
309:         else
310:           store_password = @store_password
311:         end
312:         @password = store_password ? passwd : nil
313: 
314:         passwd
315:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 263
263:       def prepare_connection(options)
264:       end

Attempts to reconnect up to the number of times allowed If forced, try once then fail with ConnectionError if not connected.

[Source]

     # File lib/active_ldap/adapter/base.rb, line 567
567:       def reconnect(options={})
568:         options = options.dup
569:         force = options[:force]
570:         retry_limit = options[:retry_limit] || @retry_limit
571:         retry_wait = options[:retry_wait] || @retry_wait
572:         options[:reconnect_attempts] ||= 0
573: 
574:         loop do
575:           @logger.debug {_('Attempting to reconnect')}
576:           disconnect!
577: 
578:           # Reset the attempts if this was forced.
579:           options[:reconnect_attempts] = 0 if force
580:           options[:reconnect_attempts] += 1 if retry_limit >= 0
581:           begin
582:             connect(options)
583:             break
584:           rescue AuthenticationError
585:             raise
586:           rescue => detail
587:             @logger.error do
588:               _("Reconnect to server failed: %s\n" \
589:                 "Reconnect to server failed backtrace:\n" \
590:                 "%s") % [detail.exception, detail.backtrace.join("\n")]
591:             end
592:             # Do not loop if forced
593:             raise ConnectionError, detail.message if force
594:           end
595: 
596:           unless can_reconnect?(options)
597:             raise ConnectionError,
598:                   _('Giving up trying to reconnect to LDAP server.')
599:           end
600: 
601:           # Sleep before looping
602:           sleep retry_wait
603:         end
604: 
605:         true
606:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 608
608:       def reconnect_if_need(options={})
609:         return if connecting?
610:         with_timeout(false, options) do
611:           reconnect(options)
612:         end
613:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 634
634:       def root_dse(attrs, options={})
635:         search(:base => "",
636:                :scope => :base,
637:                :attributes => attrs).collect do |dn, attributes|
638:           attributes
639:         end
640:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 624
624:       def root_dse_values(key, options={})
625:         dse = root_dse([key], options)[0]
626:         return [] if dse.nil?
627:         normalized_key = key.downcase
628:         dse.each do |_key, _value|
629:           return _value if _key.downcase == normalized_key
630:         end
631:         []
632:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 336
336:       def sasl_bind(bind_dn, options={})
337:         # Get all SASL mechanisms
338:         mechanisms = operation(options) do
339:           root_dse_values("supportedSASLMechanisms")
340:         end
341: 
342:         if options.has_key?(:sasl_quiet)
343:           sasl_quiet = options[:sasl_quiet]
344:         else
345:           sasl_quiet = @sasl_quiet
346:         end
347: 
348:         sasl_mechanisms = options[:sasl_mechanisms] || @sasl_mechanisms
349:         sasl_mechanisms.each do |mechanism|
350:           next unless mechanisms.include?(mechanism)
351:           return true if yield(bind_dn, mechanism, sasl_quiet)
352:         end
353:         false
354:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 356
356:       def simple_bind(bind_dn, options={})
357:         return false unless bind_dn
358: 
359:         passwd = password(bind_dn, options)
360:         return false unless passwd
361: 
362:         if passwd.empty?
363:           if options[:allow_anonymous]
364:             @logger.info {_("Skip simple bind with empty password.")}
365:             return false
366:           else
367:             raise AuthenticationError,
368:                   _("Can't use empty password for simple bind.")
369:           end
370:         end
371: 
372:         begin
373:           yield(bind_dn, passwd)
374:         rescue LdapError::InvalidDnSyntax
375:           raise DistinguishedNameInvalid.new(bind_dn)
376:         rescue LdapError::InvalidCredentials
377:           false
378:         end
379:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 647
647:       def target
648:         return nil if @uri.nil?
649:         if @with_start_tls
650:           "#{@uri}(StartTLS)"
651:         else
652:           @uri
653:         end
654:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 317
317:       def with_timeout(try_reconnect=true, options={}, &block)
318:         n_retries = 0
319:         retry_limit = options[:retry_limit] || @retry_limit
320:         begin
321:           Timeout.alarm(@timeout, &block)
322:         rescue Timeout::Error => e
323:           @logger.error {_('Requested action timed out.')}
324:           if @retry_on_timeout and retry_limit < 0 and n_retries <= retry_limit
325:             if connecting?
326:               retry
327:             elsif try_reconnect
328:               retry if with_timeout(false, options) {reconnect(options)}
329:             end
330:           end
331:           @logger.error {e.message}
332:           raise TimeoutError, e.message
333:         end
334:       end

[Validate]