lib/net/ldap.rb in net-ldap-0.10.1 vs lib/net/ldap.rb in net-ldap-0.11

- old
+ new

@@ -24,10 +24,11 @@ require 'net/ldap/password' require 'net/ldap/entry' require 'net/ldap/instrumentation' require 'net/ldap/connection' require 'net/ldap/version' +require 'net/ldap/error' # == Quick-start for the Impatient # === Quick Example of a user-authentication against an LDAP directory: # # require 'rubygems' @@ -244,12 +245,10 @@ # and then keeps it open while it executes a user-supplied block. # Net::LDAP#open closes the connection on completion of the block. class Net::LDAP include Net::LDAP::Instrumentation - class LdapError < StandardError; end - SearchScope_BaseObject = 0 SearchScope_SingleLevel = 1 SearchScope_WholeSubtree = 2 SearchScopes = [ SearchScope_BaseObject, SearchScope_SingleLevel, SearchScope_WholeSubtree ] @@ -664,20 +663,15 @@ def open # First we make a connection and then a binding, but we don't do # anything with the bind results. We then pass self to the caller's # block, where he will execute his LDAP operations. Of course they will # all generate auth failures if the bind was unsuccessful. - raise Net::LDAP::LdapError, "Open already in progress" if @open_connection + raise Net::LDAP::AlreadyOpenedError, "Open already in progress" if @open_connection instrument "open.net_ldap" do |payload| begin - @open_connection = - Net::LDAP::Connection.new \ - :host => @host, - :port => @port, - :encryption => @encryption, - :instrumentation_service => @instrumentation_service + @open_connection = new_connection payload[:connection] = @open_connection payload[:bind] = @open_connection.bind(@auth) yield self ensure @open_connection.close if @open_connection @@ -743,31 +737,15 @@ args[:base] ||= @base return_result_set = args[:return_result] != false result_set = return_result_set ? [] : nil instrument "search.net_ldap", args do |payload| - if @open_connection - @result = @open_connection.search(args) { |entry| + @result = use_connection(args) do |conn| + conn.search(args) { |entry| result_set << entry if result_set yield entry if block_given? } - else - begin - conn = Net::LDAP::Connection.new \ - :host => @host, - :port => @port, - :encryption => @encryption, - :instrumentation_service => @instrumentation_service - if (@result = conn.bind(args[:auth] || @auth)).result_code == Net::LDAP::ResultCodeSuccess - @result = conn.search(args) { |entry| - result_set << entry if result_set - yield entry if block_given? - } - end - ensure - conn.close if conn - end end if return_result_set unless @result.nil? if ResultCodesSearchSuccess.include?(@result.result_code) @@ -842,15 +820,11 @@ if @open_connection payload[:connection] = @open_connection payload[:bind] = @result = @open_connection.bind(auth) else begin - conn = Connection.new \ - :host => @host, - :port => @port, - :encryption => @encryption, - :instrumentation_service => @instrumentation_service + conn = new_connection payload[:connection] = conn payload[:bind] = @result = conn.bind(auth) ensure conn.close if conn end @@ -944,26 +918,12 @@ # Net::LDAP.open(:host => host) do |ldap| # ldap.add(:dn => dn, :attributes => attr) # end def add(args) instrument "add.net_ldap", args do |payload| - if @open_connection - @result = @open_connection.add(args) - else - @result = 0 - begin - conn = Connection.new \ - :host => @host, - :port => @port, - :encryption => @encryption, - :instrumentation_service => @instrumentation_service - if (@result = conn.bind(args[:auth] || @auth)).result_code == Net::LDAP::ResultCodeSuccess - @result = conn.add(args) - end - ensure - conn.close if conn - end + @result = use_connection(args) do |conn| + conn.add(args) end @result.success? end end @@ -1048,28 +1008,13 @@ # call are not interleaved with other modification-requests received # simultaneously by the server. It bears repeating that this concurrency # does _not_ imply transactional atomicity, which LDAP does not provide. def modify(args) instrument "modify.net_ldap", args do |payload| - if @open_connection - @result = @open_connection.modify(args) - else - @result = 0 - begin - conn = Connection.new \ - :host => @host, - :port => @port, - :encryption => @encryption, - :instrumentation_service => @instrumentation_service - if (@result = conn.bind(args[:auth] || @auth)).result_code == Net::LDAP::ResultCodeSuccess - @result = conn.modify(args) - end - ensure - conn.close if conn - end + @result = use_connection(args) do |conn| + conn.modify(args) end - @result.success? end end # Add a value to an attribute. Takes the full DN of the entry to modify, @@ -1125,26 +1070,12 @@ # Rename an entry on the remote DIS by changing the last RDN of its DN. # # _Documentation_ _stub_ def rename(args) instrument "rename.net_ldap", args do |payload| - if @open_connection - @result = @open_connection.rename(args) - else - @result = 0 - begin - conn = Connection.new \ - :host => @host, - :port => @port, - :encryption => @encryption, - :instrumentation_service => @instrumentation_service - if (@result = conn.bind(args[:auth] || @auth)).result_code == Net::LDAP::ResultCodeSuccess - @result = conn.rename(args) - end - ensure - conn.close if conn - end + @result = use_connection(args) do |conn| + conn.rename(args) end @result.success? end end alias_method :modify_rdn, :rename @@ -1158,26 +1089,12 @@ # # dn = "mail=deleteme@example.com, ou=people, dc=example, dc=com" # ldap.delete :dn => dn def delete(args) instrument "delete.net_ldap", args do |payload| - if @open_connection - @result = @open_connection.delete(args) - else - @result = 0 - begin - conn = Connection.new \ - :host => @host, - :port => @port, - :encryption => @encryption, - :instrumentation_service => @instrumentation_service - if (@result = conn.bind(args[:auth] || @auth)).result_code == Net::LDAP::ResultCodeSuccess - @result = conn.delete(args) - end - ensure - conn.close - end + @result = use_connection(args) do |conn| + conn.delete(args) end @result.success? end end @@ -1274,7 +1191,39 @@ # it returns binary data in the rfc2696_cookie which throws an # encoding exception breaking searching. return false if @force_no_page @server_caps ||= search_root_dse @server_caps[:supportedcontrol].include?(Net::LDAP::LDAPControls::PAGED_RESULTS) + end + + private + + # Yields an open connection if there is one, otherwise establishes a new + # connection, binds, and yields it. If binding fails, it will return the + # result from that, and :use_connection: will not yield at all. If not + # the return value is whatever is returned from the block. + def use_connection(args) + if @open_connection + yield @open_connection + else + begin + conn = new_connection + if (result = conn.bind(args[:auth] || @auth)).result_code == Net::LDAP::ResultCodeSuccess + yield conn + else + return result + end + ensure + conn.close if conn + end + end + end + + # Establish a new connection to the LDAP server + def new_connection + Net::LDAP::Connection.new \ + :host => @host, + :port => @port, + :encryption => @encryption, + :instrumentation_service => @instrumentation_service end end # class LDAP