ruby-activeldap-debug 0.5.7 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -899,18 +899,22 @@
899
899
  # package, and I'd like to see it prove helpful to more people than just myself.
900
900
  #
901
901
 
902
-
902
+ # Blanket warning hiding. Remove for debugging
903
+ $VERBOSE, verbose = false, $VERBOSE
903
904
 
904
905
  require 'activeldap/base'
905
906
  require 'activeldap/associations'
906
907
  require 'activeldap/configuration'
907
908
  require 'activeldap/schema2'
908
909
 
910
+
909
911
  module ActiveLDAP
910
- VERSION = "0.5.7"
912
+ VERSION = "0.5.8"
911
913
  end
912
914
 
913
915
  ActiveLDAP::Base.class_eval do
914
916
  include ActiveLDAP::Configuration
915
917
  include ActiveLDAP::Associations
916
918
  end
919
+
920
+ $VERBOSE = verbose
@@ -41,7 +41,11 @@ module ActiveLDAP
41
41
 
42
42
  # Return the full base of the class
43
43
  def base
44
- "#{prefix},\#{super}"
44
+ if "#{prefix}".empty?
45
+ return "\#{super}"
46
+ else
47
+ return "#{prefix},\#{super}"
48
+ end
45
49
  end
46
50
 
47
51
  # Return the expected DN attribute of an object
@@ -175,6 +175,7 @@ module ActiveLDAP
175
175
  # :base overwrites Base.base - this affects EVERYTHING
176
176
  # :try_sasl indicates that a SASL bind should be attempted when binding to the server (default: false)
177
177
  # :allow_anonymous indicates that a true anonymous bind is allowed when trying to bind to the server (default: true)
178
+ # :retries - indicates the number of attempts to reconnect that will be undertaken when a stale connection occurs.
178
179
  def Base.connect(config={}) # :user, :password_block, :logger
179
180
  # Process config
180
181
  # Class options
@@ -182,6 +183,7 @@ module ActiveLDAP
182
183
  @@config = {}
183
184
  @@config[:host] = config[:host] || @@host
184
185
  @@config[:port] = config[:port] || @@port
186
+ @@config[:retries] = config[:retries] || 3
185
187
  if config[:base]
186
188
  Base.class_eval <<-"end_eval"
187
189
  def Base.base
@@ -214,31 +216,8 @@ module ActiveLDAP
214
216
  # Setup bind credentials
215
217
  @@config[:user] = ENV['USER'] unless @@config[:user]
216
218
 
217
- # Connect to LDAP
218
- begin
219
- # SSL using START_TLS
220
- @@conn = LDAP::SSLConn.new(@@config[:host], @@config[:port], true)
221
- rescue
222
- @@logger.warn "Warning: Failed to connect using TLS!"
223
- begin
224
- @@logger.warn "Warning: Attempting SSL connection . . ."
225
- @@conn = LDAP::SSLConn.new(@@config[:host], @@config[:port], false)
226
- # HACK: Load the schema here because otherwise you can't tell if the
227
- # HACK: SSLConn is a real SSL connection.
228
- @@schema = @@conn.schema() if @@schema.nil?
229
- rescue
230
- @@logger.warn "Warning: Attempting unencrypted connection . . ."
231
- @@conn = LDAP::Conn.new(@@config[:host], @@config[:port])
232
- end
233
- end
234
- @@logger.debug "Connected to #{@@config[:host]}:#{@@config[:port]}."
235
-
236
- # Enforce LDAPv3
237
- @@conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
238
-
239
- # Authenticate
240
- do_bind
241
-
219
+ do_connect()
220
+
242
221
  # Load Schema (if not straight SSL...)
243
222
  begin
244
223
  @@schema = @@conn.schema() if @@schema.nil?
@@ -254,7 +233,11 @@ module ActiveLDAP
254
233
  # This method deletes the LDAP connection object.
255
234
  # This does NOT reset any overridden values from a Base.connect call.
256
235
  def Base.close
257
- @@conn.unbind unless @@conn.nil?
236
+ begin
237
+ @@conn.unbind unless @@conn.nil?
238
+ rescue
239
+ # Doesn't matter.
240
+ end
258
241
  @@conn = nil
259
242
  # Make sure it is cleaned up
260
243
  ObjectSpace.garbage_collect
@@ -296,6 +279,7 @@ module ActiveLDAP
296
279
  values = []
297
280
  config[:attrs] = config[:attrs].to_a # just in case
298
281
 
282
+ tries = 0
299
283
  begin
300
284
  @@conn.search(config[:base], config[:scope], config[:filter], config[:attrs]) do |m|
301
285
  res = {}
@@ -308,8 +292,16 @@ module ActiveLDAP
308
292
  values.push(res)
309
293
  end
310
294
  rescue RuntimeError => detail
311
- @@logger.debug "No matches for #{config[:filter]} and attrs #{config[:attrs]}"
312
- # Do nothing on failure
295
+ #TODO# Check for 'No message' when retrying
296
+ # The connection may have gone stale. Let's reconnect and retry.
297
+ if tries > @max_retries
298
+ # Do nothing on failure
299
+ @@logger.debug "No matches for #{config[:filter]} and attrs #{config[:attrs]}"
300
+ end
301
+ tries += 1
302
+ # Reconnect and rebind.
303
+ do_connect()
304
+ retry
313
305
  end
314
306
  return values
315
307
  end
@@ -351,6 +343,7 @@ module ActiveLDAP
351
343
 
352
344
  matches = []
353
345
 
346
+ tries = 0
354
347
  begin
355
348
  # Get some attributes
356
349
  @@conn.search(base(), LDAP::LDAP_SCOPE_SUBTREE, "(#{attr}=#{val})") do |m|
@@ -364,8 +357,16 @@ module ActiveLDAP
364
357
  end
365
358
  end
366
359
  rescue RuntimeError => detail
367
- @@logger.debug "No matches for #{attr}=#{val}"
368
- # Do nothing on failure
360
+ #todo# check for 'no message' when retrying
361
+ # the connection may have gone stale. let's reconnect and retry.
362
+ if tries > @max_retries
363
+ # do nothing on failure
364
+ @@logger.debug "no matches for #{attr}=#{val}"
365
+ end
366
+ tries += 1
367
+ # reconnect and rebind.
368
+ do_connect()
369
+ retry
369
370
  end
370
371
  return nil
371
372
  end
@@ -403,6 +404,7 @@ module ActiveLDAP
403
404
 
404
405
  matches = []
405
406
 
407
+ tries = 0
406
408
  begin
407
409
  # Get some attributes
408
410
  @@conn.search(base(), LDAP::LDAP_SCOPE_SUBTREE, "(#{attr}=#{val})") do |m|
@@ -416,9 +418,16 @@ module ActiveLDAP
416
418
  end
417
419
  end
418
420
  rescue RuntimeError => detail
419
- #p @@conn.err2string(@@conn.err)
420
- @@logger.debug "No matches for #{attr}=#{val}"
421
- # Do nothing on failure
421
+ #todo# check for 'no message' when retrying
422
+ # the connection may have gone stale. let's reconnect and retry.
423
+ if tries > @max_retries
424
+ # do nothing on failure
425
+ @@logger.debug "no matches for #{attr}=#{val}"
426
+ end
427
+ tries += 1
428
+ # reconnect and rebind.
429
+ do_connect()
430
+ retry
422
431
  end
423
432
  return matches
424
433
  end
@@ -499,6 +508,7 @@ module ActiveLDAP
499
508
  @data = {} # where the r/w entry data is stored
500
509
  @ldap_data = {} # original ldap entry data
501
510
  @attr_methods = {} # list of valid method calls for attributes used for dereferencing
511
+ @last_oc = nil # for use in other methods for "caching"
502
512
 
503
513
  # Break val apart if it is a dn
504
514
  if val.match(/^#{dnattr()}=([^,=]+),#{base()}$/i)
@@ -516,6 +526,7 @@ module ActiveLDAP
516
526
  send(:apply_objectclass, required_classes())
517
527
  else # do a search then
518
528
  # Search for the existing entry
529
+ tries = 0
519
530
  begin
520
531
  # Get some attributes
521
532
  Base.connection.search("#{dnattr()}=#{val},#{base()}", LDAP::LDAP_SCOPE_SUBTREE, "objectClass=*") do |m|
@@ -546,7 +557,24 @@ module ActiveLDAP
546
557
  @ldap_data.each do |pair|
547
558
  send(:attribute_method=, pair[0], pair[1].dup)
548
559
  end
549
-
560
+ rescue RuntimeError => detail
561
+ #todo# check for 'no message' when retrying
562
+ # the connection may have gone stale. let's reconnect and retry.
563
+ if tries > @max_retries
564
+ @exists = false
565
+ # Create what should be the authoritative DN
566
+ @dn = "#{dnattr()}=#{val},#{base()}"
567
+ send(:apply_objectclass, required_classes())
568
+
569
+ # Setup dn attribute (later rdn too!)
570
+ attr_sym = "#{dnattr()}=".to_sym
571
+ @@logger.debug("new: setting dnattr: #{dnattr()} = #{val}")
572
+ send(attr_sym, val)
573
+ end
574
+ tries += 1
575
+ # reconnect and rebind.
576
+ do_connect()
577
+ retry
550
578
  rescue LDAP::ResultError
551
579
  @exists = false
552
580
  # Create what should be the authoritative DN
@@ -640,9 +668,20 @@ module ActiveLDAP
640
668
  # Delete this entry from LDAP
641
669
  def delete
642
670
  @@logger.debug("stub: delete called")
671
+ tries = 0
643
672
  begin
644
673
  @@conn.delete(@dn)
645
674
  @exists = false
675
+ rescue RuntimeError => detail
676
+ #todo# check for 'no message' when retrying
677
+ # the connection may have gone stale. let's reconnect and retry.
678
+ if tries > @max_retries
679
+ raise DeleteError, "Failed to delete LDAP entry: '#{@dn}'"
680
+ end
681
+ tries += 1
682
+ # reconnect and rebind.
683
+ do_connect()
684
+ retry
646
685
  rescue LDAP::ResultError => detail
647
686
  raise DeleteError, "Failed to delete LDAP entry: '#{@dn}'"
648
687
  end
@@ -669,7 +708,7 @@ module ActiveLDAP
669
708
  # We can't reuse @ldap_data because an exception would leave
670
709
  # an object in an unknown state
671
710
  @@logger.debug("#write: dup'ing @ldap_data")
672
- ldap_data = @ldap_data.dup
711
+ ldap_data = Marshal.load(Marshal.dump(@ldap_data))
673
712
  @@logger.debug("#write: dup finished @ldap_data")
674
713
  @@logger.debug("#write: expanding subtypes in @ldap_data")
675
714
  ldap_data.keys.each do |key|
@@ -689,7 +728,7 @@ module ActiveLDAP
689
728
 
690
729
  # Expand subtypes to real data entries, but leave @data alone
691
730
  @@logger.debug("#write: dup'ing @data")
692
- data = @data.dup
731
+ data = Marshal.load(Marshal.dump(@data))
693
732
  @@logger.debug("#write: finished dup'ing @data")
694
733
  @@logger.debug("#write: expanding subtypes for @data")
695
734
  data.keys.each do |key|
@@ -768,10 +807,21 @@ module ActiveLDAP
768
807
  end
769
808
  end
770
809
  @@logger.debug("#write: traversing data complete")
810
+ tries = 0
771
811
  begin
772
812
  @@logger.debug("#write: modifying #{@dn}")
773
813
  @@conn.modify(@dn, entry)
774
814
  @@logger.debug("#write: modify successful")
815
+ rescue RuntimeError => detail
816
+ #todo# check for 'no message' when retrying
817
+ # the connection may have gone stale. let's reconnect and retry.
818
+ if tries > @max_retries
819
+ raise WriteError, "Could not update LDAP entry: #{detail}"
820
+ end
821
+ tries += 1
822
+ # reconnect and rebind.
823
+ do_connect()
824
+ retry
775
825
  rescue => detail
776
826
  raise WriteError, "Could not update LDAP entry: #{detail}"
777
827
  end
@@ -795,17 +845,27 @@ module ActiveLDAP
795
845
  entry.push(LDAP.mod(LDAP::LDAP_MOD_ADD|binary, pair[0], pair[1]))
796
846
  end
797
847
  end
848
+ tries = 0
798
849
  begin
799
850
  @@logger.debug("#write: adding #{@dn}")
800
851
  @@conn.add(@dn, entry)
801
852
  @@logger.debug("#write: add successful")
802
853
  @exists = true
854
+ rescue RuntimeError => e
855
+ # The connection may have gone stale. Let's reconnect and retry.
856
+ if tries > @max_retries
857
+ raise WriteError, "Could not add LDAP entry[#{Base.connection.err2string(Base.connection.err)}]: #{detail}"
858
+ end
859
+ tries += 1
860
+ # Reconnect and rebind.
861
+ do_connect()
862
+ retry
803
863
  rescue LDAP::ResultError => detail
804
864
  raise WriteError, "Could not add LDAP entry[#{Base.connection.err2string(Base.connection.err)}]: #{detail}"
805
865
  end
806
866
  end
807
867
  @@logger.debug("#write: resetting @ldap_data to a dup of @data")
808
- @ldap_data = @data.dup
868
+ @ldap_data = Marshal.load(Marshal.dump(@data))
809
869
  @@logger.debug("#write: @ldap_data reset complete")
810
870
  @@logger.debug("stub: write exitted")
811
871
  end
@@ -936,16 +996,16 @@ module ActiveLDAP
936
996
  # Build |data| from schema
937
997
  # clear attr_method mapping first
938
998
  @attr_methods = {}
939
- @must = []
940
- @may = []
999
+ @must = []
1000
+ @may = []
941
1001
  new_oc.each do |objc|
942
1002
  # get all attributes for the class
943
1003
  attributes = Base.schema.class_attributes(objc.to_s)
944
- @must += attributes[:must]
945
- @may += attributes[:may]
1004
+ @must += attributes[:must]
1005
+ @may += attributes[:may]
946
1006
  end
947
- @must.uniq!
948
- @may.uniq!
1007
+ @must.uniq!
1008
+ @may.uniq!
949
1009
  (@must+@may).each do |attr|
950
1010
  # Update attr_method with appropriate
951
1011
  define_attribute_methods(attr)
@@ -1053,6 +1113,36 @@ module ActiveLDAP
1053
1113
  end
1054
1114
 
1055
1115
 
1116
+ # Performs the actually connection. This separate so that it may
1117
+ # be called to refresh stale connections.
1118
+ def Base.do_connect()
1119
+ # Connect to LDAP
1120
+ begin
1121
+ # SSL using START_TLS
1122
+ @@conn = LDAP::SSLConn.new(@@config[:host], @@config[:port], true)
1123
+ rescue
1124
+ @@logger.warn "Warning: Failed to connect using TLS!"
1125
+ begin
1126
+ @@logger.warn "Warning: Attempting SSL connection . . ."
1127
+ @@conn = LDAP::SSLConn.new(@@config[:host], @@config[:port], false)
1128
+ # HACK: Load the schema here because otherwise you can't tell if the
1129
+ # HACK: SSLConn is a real SSL connection.
1130
+ @@schema = @@conn.schema() if @@schema.nil?
1131
+ rescue
1132
+ @@logger.warn "Warning: Attempting unencrypted connection . . ."
1133
+ @@conn = LDAP::Conn.new(@@config[:host], @@config[:port])
1134
+ end
1135
+ end
1136
+ @@logger.debug "Connected to #{@@config[:host]}:#{@@config[:port]}."
1137
+
1138
+ # Enforce LDAPv3
1139
+ @@conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
1140
+
1141
+ # Authenticate
1142
+ do_bind
1143
+ end
1144
+
1145
+
1056
1146
  # Wrapper all bind activity
1057
1147
  def Base.do_bind()
1058
1148
  bind_dn = @@config[:bind_format] % [@@config[:user]]
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.10
2
+ rubygems_version: 0.8.4
3
3
  specification_version: 1
4
4
  name: ruby-activeldap-debug
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.5.7
7
- date: 2005-05-24
6
+ version: 0.5.8
7
+ date: 2005-10-31
8
8
  summary: Ruby/ActiveLDAP is a object-oriented API to LDAP
9
9
  require_paths:
10
10
  - lib
@@ -29,9 +29,9 @@ authors:
29
29
  files:
30
30
  - lib/activeldap
31
31
  - lib/activeldap.rb
32
- - lib/activeldap/configuration.rb
33
32
  - lib/activeldap/associations.rb
34
33
  - lib/activeldap/base.rb
34
+ - lib/activeldap/configuration.rb
35
35
  - lib/activeldap/schema2.rb
36
36
  test_files: []
37
37
  rdoc_options: []