You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

auth_source_ldap.rb 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. # redMine - project management software
  2. # Copyright (C) 2006 Jean-Philippe Lang
  3. #
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU General Public License
  6. # as published by the Free Software Foundation; either version 2
  7. # of the License, or (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. require 'net/ldap'
  18. require 'iconv'
  19. class AuthSourceLdap < AuthSource
  20. validates_presence_of :host, :port, :attr_login
  21. validates_presence_of :attr_firstname, :attr_lastname, :attr_mail, :if => Proc.new { |a| a.onthefly_register? }
  22. def after_initialize
  23. self.port = 389 if self.port == 0
  24. end
  25. def authenticate(login, password)
  26. return nil if login.blank? || password.blank?
  27. attrs = []
  28. # get user's DN
  29. ldap_con = initialize_ldap_con(self.account, self.account_password)
  30. login_filter = Net::LDAP::Filter.eq( self.attr_login, login )
  31. object_filter = Net::LDAP::Filter.eq( "objectClass", "*" )
  32. dn = String.new
  33. ldap_con.search( :base => self.base_dn,
  34. :filter => object_filter & login_filter,
  35. # only ask for the DN if on-the-fly registration is disabled
  36. :attributes=> (onthefly_register? ? ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail] : ['dn'])) do |entry|
  37. dn = entry.dn
  38. attrs = [:firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname),
  39. :lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
  40. :mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
  41. :auth_source_id => self.id ] if onthefly_register?
  42. end
  43. return nil if dn.empty?
  44. logger.debug "DN found for #{login}: #{dn}" if logger && logger.debug?
  45. # authenticate user
  46. ldap_con = initialize_ldap_con(dn, password)
  47. return nil unless ldap_con.bind
  48. # return user's attributes
  49. logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
  50. attrs
  51. rescue Net::LDAP::LdapError => text
  52. raise "LdapError: " + text
  53. end
  54. # test the connection to the LDAP
  55. def test_connection
  56. ldap_con = initialize_ldap_con(self.account, self.account_password)
  57. ldap_con.open { }
  58. rescue Net::LDAP::LdapError => text
  59. raise "LdapError: " + text
  60. end
  61. def auth_method_name
  62. "LDAP"
  63. end
  64. private
  65. def initialize_ldap_con(ldap_user, ldap_password)
  66. options = { :host => self.host,
  67. :port => self.port,
  68. :encryption => (self.tls ? :simple_tls : nil)
  69. }
  70. options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank?
  71. Net::LDAP.new options
  72. end
  73. def self.get_attr(entry, attr_name)
  74. entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
  75. end
  76. end