ruby-net-ldap 0.0.3 → 0.0.4
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.
- 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
|