ruby-net-ldap 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +12 -0
- data/lib/net/ldap.rb +76 -17
- data/lib/net/ldap/filter.rb +6 -2
- metadata +2 -2
data/ChangeLog
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
= Net::LDAP Changelog
|
2
2
|
|
3
|
+
== Net::LDAP 0.0.4: August 15, 2006
|
4
|
+
* Undeprecated Net::LDAP#modify. Thanks to Justin Forder for
|
5
|
+
providing the rationale for this.
|
6
|
+
* Added a much-expanded set of special characters to the parser
|
7
|
+
for RFC-2254 filters. Thanks to Andre Nathan.
|
8
|
+
* Changed Net::LDAP#search so you can pass it a filter in string form.
|
9
|
+
The conversion to a Net::LDAP::Filter now happens automatically.
|
10
|
+
* Implemented Net::LDAP#bind_as (preliminary and subject to change).
|
11
|
+
Thanks for Simon Claret for valuable suggestions and for helping test.
|
12
|
+
* Fixed bug in Net::LDAP#open that was preventing #open from being
|
13
|
+
called more than one on a given Net::LDAP object.
|
14
|
+
|
3
15
|
== Net::LDAP 0.0.3: July 26, 2006
|
4
16
|
* Added simple TLS encryption.
|
5
17
|
Thanks to Garett Shulman for suggestions and for helping test.
|
data/lib/net/ldap.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: ldap.rb
|
1
|
+
# $Id: ldap.rb 154 2006-08-15 09:35:43Z blackhedd $
|
2
2
|
#
|
3
3
|
# Net::LDAP for Ruby
|
4
4
|
#
|
@@ -263,7 +263,7 @@ module Net
|
|
263
263
|
|
264
264
|
class LdapError < Exception; end
|
265
265
|
|
266
|
-
VERSION = "0.0.
|
266
|
+
VERSION = "0.0.4"
|
267
267
|
|
268
268
|
|
269
269
|
SearchScope_BaseObject = 0
|
@@ -543,6 +543,7 @@ module Net
|
|
543
543
|
@open_connection.bind @auth
|
544
544
|
yield self
|
545
545
|
@open_connection.close
|
546
|
+
@open_connection = nil
|
546
547
|
end
|
547
548
|
|
548
549
|
|
@@ -692,9 +693,9 @@ module Net
|
|
692
693
|
# on it. Otherwise, connect, bind, and disconnect.
|
693
694
|
# The latter operation is obviously useful only as an auth check.
|
694
695
|
#
|
695
|
-
def bind
|
696
|
+
def bind auth=@auth
|
696
697
|
if @open_connection
|
697
|
-
@result = @open_connection.bind
|
698
|
+
@result = @open_connection.bind auth
|
698
699
|
else
|
699
700
|
conn = Connection.new( :host => @host, :port => @port , :encryption => @encryption)
|
700
701
|
@result = conn.bind @auth
|
@@ -706,18 +707,64 @@ module Net
|
|
706
707
|
|
707
708
|
#
|
708
709
|
# #bind_as is for testing authentication credentials.
|
709
|
-
# Most likely a "standard" name (like a CN or an email
|
710
|
-
# address) will be presented along with a password.
|
711
|
-
# We'll bind with the main credential given in the
|
712
|
-
# constructor, query the full DN of the user given
|
713
|
-
# to us as a parameter, then unbind and rebind as the
|
714
|
-
# new user.
|
715
710
|
#
|
716
|
-
#
|
711
|
+
# As described under #bind, most LDAP servers require that you supply a complete DN
|
712
|
+
# as a binding-credential, along with an authenticator such as a password.
|
713
|
+
# But for many applications (such as authenticating users to a Rails application),
|
714
|
+
# you often don't have a full DN to identify the user. You usually get a simple
|
715
|
+
# identifier like a username or an email address, along with a password.
|
716
|
+
# #bind_as allows you to authenticate these user-identifiers.
|
717
|
+
#
|
718
|
+
# #bind_as is a combination of a search and an LDAP binding. First, it connects and
|
719
|
+
# binds to the directory as normal. Then it searches the directory for an entry
|
720
|
+
# corresponding to the email address, username, or other string that you supply.
|
721
|
+
# If the entry exists, then #bind_as will <b>re-bind</b> as that user with the
|
722
|
+
# password (or other authenticator) that you supply.
|
723
|
+
#
|
724
|
+
# #bind_as takes the same parameters as #search, <i>with the addition of an
|
725
|
+
# authenticator.</i> Currently, this authenticator must be <tt>:password</tt>.
|
726
|
+
# Its value may be either a String, or a +proc+ that returns a String.
|
727
|
+
# #bind_as returns +false+ on failure. On success, it returns a result set,
|
728
|
+
# just as #search does. This result set is an Array of objects of
|
729
|
+
# type Net::LDAP::Entry. It contains the directory attributes corresponding to
|
730
|
+
# the user. (Just test whether the return value is logically true, if you don't
|
731
|
+
# need this additional information.)
|
732
|
+
#
|
733
|
+
# Here's how you would use #bind_as to authenticate an email address and password:
|
717
734
|
#
|
718
|
-
|
735
|
+
# require 'net/ldap'
|
736
|
+
#
|
737
|
+
# user,psw = "joe_user@yourcompany.com", "joes_psw"
|
738
|
+
#
|
739
|
+
# ldap = Net::LDAP.new
|
740
|
+
# ldap.host = "192.168.0.100"
|
741
|
+
# ldap.port = 389
|
742
|
+
# ldap.auth "cn=manager,dc=yourcompany,dc=com", "topsecret"
|
743
|
+
#
|
744
|
+
# result = ldap.bind_as(
|
745
|
+
# :base => "dc=yourcompany,dc=com",
|
746
|
+
# :filter => "(mail=#{user})",
|
747
|
+
# :password => psw
|
748
|
+
# )
|
749
|
+
# if result
|
750
|
+
# puts "Authenticated #{result.first.dn}"
|
751
|
+
# else
|
752
|
+
# puts "Authentication FAILED."
|
753
|
+
# end
|
754
|
+
def bind_as args={}
|
755
|
+
result = false
|
756
|
+
open {|me|
|
757
|
+
rs = search args
|
758
|
+
if rs and rs.first and dn = rs.first.dn
|
759
|
+
password = args[:password]
|
760
|
+
password = password.call if password.respond_to?(:call)
|
761
|
+
result = rs if bind :method => :simple, :username => dn, :password => password
|
762
|
+
end
|
763
|
+
}
|
764
|
+
result
|
719
765
|
end
|
720
766
|
|
767
|
+
|
721
768
|
# Adds a new entry to the remote LDAP server.
|
722
769
|
# Supported arguments:
|
723
770
|
# :dn :: Full DN of the new entry
|
@@ -757,8 +804,6 @@ module Net
|
|
757
804
|
end
|
758
805
|
|
759
806
|
|
760
|
-
# _DEPRECATED_ - Please use #add_attribute, #replace_attribute, or #delete_attribute.
|
761
|
-
#
|
762
807
|
# Modifies the attribute values of a particular entry on the LDAP directory.
|
763
808
|
# Takes a hash with arguments. Supported arguments are:
|
764
809
|
# :dn :: (the full DN of the entry whose attributes are to be modified)
|
@@ -768,6 +813,9 @@ module Net
|
|
768
813
|
# succeeded or failed, with extended information available by calling
|
769
814
|
# #get_operation_result.
|
770
815
|
#
|
816
|
+
# Also see #add_attribute, #replace_attribute, or #delete_attribute, which
|
817
|
+
# provide simpler interfaces to this functionality.
|
818
|
+
#
|
771
819
|
# The LDAP protocol provides a full and well thought-out set of operations
|
772
820
|
# for changing the values of attributes, but they are necessarily somewhat complex
|
773
821
|
# and not always intuitive. If these instructions are confusing or incomplete,
|
@@ -786,14 +834,15 @@ module Net
|
|
786
834
|
# The :add operator will, unsurprisingly, add the specified values to
|
787
835
|
# the specified attribute. If the attribute does not already exist,
|
788
836
|
# :add will create it. Most LDAP servers will generate an error if you
|
789
|
-
# to add a value that already exists.
|
837
|
+
# try to add a value that already exists.
|
790
838
|
#
|
791
839
|
# :replace will erase the current value(s) for the specified attribute,
|
792
840
|
# if there are any, and replace them with the specified value(s).
|
793
841
|
#
|
794
842
|
# :delete will remove the specified value(s) from the specified attribute.
|
795
843
|
# If you pass nil, an empty string, or an empty array as the value parameter
|
796
|
-
# to a :delete operation, the _entire_ _attribute_ will be deleted
|
844
|
+
# to a :delete operation, the _entire_ _attribute_ will be deleted, along
|
845
|
+
# with all of its values.
|
797
846
|
#
|
798
847
|
# For example:
|
799
848
|
#
|
@@ -808,13 +857,14 @@ module Net
|
|
808
857
|
# <i>(This example is contrived since you probably wouldn't add a mail
|
809
858
|
# value right before replacing the whole attribute, but it shows that order
|
810
859
|
# of execution matters. Also, many LDAP servers won't let you delete SN
|
811
|
-
# because
|
860
|
+
# because that would be a schema violation.)</i>
|
812
861
|
#
|
813
862
|
# It's essential to keep in mind that if you specify more than one operation in
|
814
863
|
# a call to #modify, most LDAP servers will attempt to perform all of the operations
|
815
864
|
# in the order you gave them.
|
816
865
|
# This matters because you may specify operations on the
|
817
866
|
# same attribute which must be performed in a certain order.
|
867
|
+
#
|
818
868
|
# Most LDAP servers will _stop_ processing your modifications if one of them
|
819
869
|
# causes an error on the server (such as a schema-constraint violation).
|
820
870
|
# If this happens, you will probably get a result code from the server that
|
@@ -825,6 +875,14 @@ module Net
|
|
825
875
|
# not be "rolled back," resulting in a partial update. This is a limitation
|
826
876
|
# of the LDAP protocol, not of Net::LDAP.
|
827
877
|
#
|
878
|
+
# The lack of transactional atomicity in LDAP means that you're usually
|
879
|
+
# better off using the convenience methods #add_attribute, #replace_attribute,
|
880
|
+
# and #delete_attribute, which are are wrappers over #modify. However, certain
|
881
|
+
# LDAP servers may provide concurrency semantics, in which the several operations
|
882
|
+
# contained in a single #modify call are not interleaved with other
|
883
|
+
# modification-requests received simultaneously by the server.
|
884
|
+
# It bears repeating that this concurrency does _not_ imply transactional
|
885
|
+
# atomicity, which LDAP does not provide.
|
828
886
|
#
|
829
887
|
def modify args
|
830
888
|
if @open_connection
|
@@ -1067,6 +1125,7 @@ module Net
|
|
1067
1125
|
#
|
1068
1126
|
def search args = {}
|
1069
1127
|
search_filter = (args && args[:filter]) || Filter.eq( "objectclass", "*" )
|
1128
|
+
search_filter = Filter.construct(search_filter) if search_filter.is_a?(String)
|
1070
1129
|
search_base = (args && args[:base]) || "dc=example,dc=com"
|
1071
1130
|
search_attributes = ((args && args[:attributes]) || []).map {|attr| attr.to_s.to_ber}
|
1072
1131
|
return_referrals = args && args[:return_referrals] == true
|
data/lib/net/ldap/filter.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: filter.rb
|
1
|
+
# $Id: filter.rb 151 2006-08-15 08:34:53Z blackhedd $
|
2
2
|
#
|
3
3
|
#
|
4
4
|
#----------------------------------------------------------------------------
|
@@ -292,6 +292,7 @@ class Filter
|
|
292
292
|
end # class Net::LDAP::Filter
|
293
293
|
|
294
294
|
|
295
|
+
|
295
296
|
class FilterParser #:nodoc:
|
296
297
|
|
297
298
|
attr_reader :filter
|
@@ -349,13 +350,16 @@ class FilterParser #:nodoc:
|
|
349
350
|
end
|
350
351
|
end
|
351
352
|
|
353
|
+
# Added a greatly-augmented filter contributed by Andre Nathan
|
354
|
+
# for detecting special characters in values. (15Aug06)
|
352
355
|
def parse_filter_branch scanner
|
353
356
|
scanner.scan /\s*/
|
354
357
|
if token = scanner.scan( /[\w\-_]+/ )
|
355
358
|
scanner.scan /\s*/
|
356
359
|
if op = scanner.scan( /\=|\<\=|\<|\>\=|\>|\!\=/ )
|
357
360
|
scanner.scan /\s*/
|
358
|
-
if value = scanner.scan( /[\w\*\.]+/ )
|
361
|
+
#if value = scanner.scan( /[\w\*\.]+/ ) (ORG)
|
362
|
+
if value = scanner.scan( /[\w\*\.\+\-@=#\$%&!]+/ )
|
359
363
|
case op
|
360
364
|
when "="
|
361
365
|
Filter.eq( token, value )
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ruby-net-ldap
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2006-
|
6
|
+
version: 0.0.4
|
7
|
+
date: 2006-08-15 00:00:00 -04:00
|
8
8
|
summary: A pure Ruby LDAP client library.
|
9
9
|
require_paths:
|
10
10
|
- lib
|