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.
- data/lib/activeldap/associations.rb +5 -1
- data/lib/activeldap/base.rb +132 -42
- data/lib/activeldap.rb +6 -2
- metadata +4 -4
@@ -41,7 +41,11 @@ module ActiveLDAP
|
|
41
41
|
|
42
42
|
# Return the full base of the class
|
43
43
|
def base
|
44
|
-
"#{prefix}
|
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
|
data/lib/activeldap/base.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
420
|
-
|
421
|
-
|
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
|
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
|
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
|
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
|
-
|
940
|
-
|
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
|
-
|
945
|
-
|
1004
|
+
@must += attributes[:must]
|
1005
|
+
@may += attributes[:may]
|
946
1006
|
end
|
947
|
-
|
948
|
-
|
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.
|
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.
|
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
|
-
date: 2005-
|
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: []
|