ruby-activeldap 0.5.7 → 0.5.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
219
+ do_connect()
234
220
 
235
-
236
- # Enforce LDAPv3
237
- @@conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
238
-
239
- # Authenticate
240
- do_bind
241
-
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
-
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
+
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
-
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
+
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
-
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
+
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
+
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
 
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
 
672
- ldap_data = @ldap_data.dup
711
+ ldap_data = Marshal.load(Marshal.dump(@ldap_data))
673
712
 
674
713
 
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
 
692
- data = @data.dup
731
+ data = Marshal.load(Marshal.dump(@data))
693
732
 
694
733
 
695
734
  data.keys.each do |key|
@@ -768,10 +807,21 @@ module ActiveLDAP
768
807
  end
769
808
  end
770
809
 
810
+ tries = 0
771
811
  begin
772
812
 
773
813
  @@conn.modify(@dn, entry)
774
814
 
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
 
800
851
  @@conn.add(@dn, entry)
801
852
 
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
 
808
- @ldap_data = @data.dup
868
+ @ldap_data = Marshal.load(Marshal.dump(@data))
809
869
 
810
870
 
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
+
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]]
data/lib/activeldap.rb CHANGED
@@ -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
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
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: []