Class ActiveLdap::Adapter::Base
In: lib/active_ldap/adapter/base.rb
lib/active_ldap/adapter/jndi.rb
lib/active_ldap/adapter/ldap.rb
lib/active_ldap/adapter/net_ldap.rb
Parent: Object
Error AttributeAssignmentError AdapterNotSpecified OperationNotPermitted RequiredObjectClassMissed ConnectionError RequiredAttributeMissed LdifInvalid LdapError DistinguishedNameNotSetError EntryNotFound 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] DistinguishedName Base Reloadable::Deprecated Reloadable::Subclasses Enumerable Ldif Collection EntryAttribute StandardError Children HasManyWrap HasMany BelongsToMany Proxy BelongsTo Common Find LDIF Delete Update GetText::Translation Normalizable GetText Parser ActiveRecord::Callbacks ActiveRecord::Validations 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 Xml JndiConnection lib/active_ldap/distinguished_name.rb lib/active_ldap/base.rb lib/active_ldap/schema/syntaxes.rb lib/active_ldap/xml.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 Update Common ModifyNameRecordLoadable AddOperationModifiable DeleteOperationModifiable ReplaceOperationModifiable ModifyRecordLoadable DeleteRecordLoadable AddRecordLoadable ContentRecordLoadable LDIF Delete Find Operations GetTextSupport Escape ClassMethods Normalizable Attributes ClassMethods Configuration ClassMethods ObjectClass lib/active_ldap/get_text/parser.rb GetText ClassMethods Callbacks Validations lib/active_ldap/adapter/jndi_connection.rb lib/active_ldap/adapter/net_ldap.rb lib/active_ldap/adapter/ldap.rb lib/active_ldap/adapter/jndi.rb Adapter Helper Translation GetTextFallback 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 197
197:       def add(dn, entries, options={})
198:         dn = ensure_dn_string(dn)
199:         begin
200:           operation(options) do
201:             yield(dn, entries)
202:           end
203:         rescue LdapError::NoSuchObject
204:           raise EntryNotFound, _("No such entry: %s") % dn
205:         rescue LdapError::InvalidDnSyntax
206:           raise DistinguishedNameInvalid.new(dn)
207:         rescue LdapError::AlreadyExists
208:           raise EntryAlreadyExist, _("%s: %s") % [$!.message, dn]
209:         rescue LdapError::StrongAuthRequired
210:           raise StrongAuthenticationRequired, _("%s: %s") % [$!.message, dn]
211:         rescue LdapError::ObjectClassViolation
212:           raise RequiredAttributeMissed, _("%s: %s") % [$!.message, dn]
213:         rescue LdapError::UnwillingToPerform
214:           raise OperationNotPermitted, _("%s: %s") % [$!.message, dn]
215:         end
216:       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 178
178:       def delete(targets, options={})
179:         targets = [targets] unless targets.is_a?(Array)
180:         return if targets.empty?
181:         begin
182:           operation(options) do
183:             targets.each do |target|
184:               target = ensure_dn_string(target)
185:               begin
186:                 yield(target)
187:               rescue LdapError::UnwillingToPerform, LdapError::InsufficientAccess
188:                 raise OperationNotPermitted, _("%s: %s") % [$!.message, target]
189:               end
190:             end
191:           end
192:         rescue LdapError::NoSuchObject
193:           raise EntryNotFound, _("No such entry: %s") % target
194:         end
195:       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 150
150:       def entry_attribute(object_classes)
151:         @entry_attributes[object_classes.uniq.sort] ||=
152:           EntryAttribute.new(schema, object_classes)
153:       end

[Source]

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

[Source]

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

[Source]

     # File lib/active_ldap/adapter/base.rb, line 235
235:       def modify_rdn(dn, new_rdn, delete_old_rdn, new_superior, options={})
236:         dn = ensure_dn_string(dn)
237:         operation(options) do
238:           yield(dn, new_rdn, delete_old_rdn, new_superior)
239:         end
240:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 146
146:       def naming_contexts
147:         root_dse_values('namingContexts')
148:       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:           schema = nil
135:           search(:base => base,
136:                  :scope => :base,
137:                  :filter => '(objectClass=subschema)',
138:                  :attributes => attrs,
139:                  :limit => 1) do |dn, attributes|
140:             schema = Schema.new(attributes)
141:           end
142:           schema || Schema.new([])
143:         end
144:       end

[Source]

     # File lib/active_ldap/adapter/base.rb, line 155
155:       def search(options={})
156:         filter = parse_filter(options[:filter]) || 'objectClass=*'
157:         attrs = options[:attributes] || []
158:         scope = ensure_scope(options[:scope] || @scope)
159:         base = options[:base]
160:         limit = options[:limit] || 0
161:         limit = nil if limit <= 0
162: 
163:         attrs = attrs.to_a # just in case
164:         base = ensure_dn_string(base)
165:         begin
166:           operation(options) do
167:             yield(base, scope, filter, attrs, limit)
168:           end
169:         rescue LdapError::NoSuchObject, LdapError::InvalidDnSyntax
170:           # Do nothing on failure
171:           @logger.info do
172:             args = [$!.class, $!.message, filter, attrs.inspect]
173:             _("Ignore error %s(%s): filter %s: attributes: %s") % args
174:           end
175:         end
176:       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 555
555:       def assert_filter_logical_operator(operator)
556:         return if operator.nil?
557:         unless filter_logical_operator?(operator)
558:           raise ArgumentError,
559:                 _("invalid logical operator: %s: available operators: %s") %
560:                   [operator.inspect, LOGICAL_OPERATORS.inspect]
561:         end
562:       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 616
616:       def can_reconnect?(options={})
617:         retry_limit = options[:retry_limit] || @retry_limit
618:         reconnect_attempts = options[:reconnect_attempts] || 0
619: 
620:         retry_limit < 0 or reconnect_attempts <= retry_limit
621:       end

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

     # File lib/active_ldap/adapter/base.rb, line 331
331:       def do_in_timeout(timeout, &block)
332:         Timeout.alarm(timeout, &block)
333:       end

[Source]

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

[Source]

     # File lib/active_ldap/adapter/base.rb, line 250
250:       def ensure_port(method)
251:         if method == :ssl
252:           URI::LDAPS::DEFAULT_PORT
253:         else
254:           URI::LDAP::DEFAULT_PORT
255:         end
256:       end

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Source]

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

[Validate]