Project

General

Profile

Patch #5690 » ldappassword.patch

change user ldap password without enum plugin - Oskar H, 2010-06-16 14:38

View differences:

app/controllers/my_controller.rb
1
# Redmine - project management software
1
 # Redmine - project management software
2 2
# Copyright (C) 2006-2009  Jean-Philippe Lang
3 3
#
4 4
# This program is free software; you can redistribute it and/or
......
84 84
    end
85 85
    if request.post?
86 86
      if @user.check_password?(params[:password])
87
        @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
88
        if @user.save
89
          flash[:notice] = l(:notice_account_password_updated)
90
          redirect_to :action => 'account'
87
        if @user.isExternal?
88
          if @user.changeExternalPassword(params[:password],params[:new_password], params[:new_password_confirmation])
89
            flash[:notice] = l(:notice_account_password_updated)
90
            redirect_to :action => 'account'
91
          else
92
            flash[:error] = l(:notice_external_password_error)
93
          end
94
        else
95
          @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
96
          if @user.save
97
            flash[:notice] = l(:notice_account_password_updated)
98
            redirect_to :action => 'account'
99
          end
91 100
        end
92 101
      else
93 102
        flash[:error] = l(:notice_account_wrong_password)
app/helpers/auth_sources_helper.rb
16 16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 17

  
18 18
module AuthSourcesHelper
19
  
20
  module Encryption
21
    # Return an array of password encryptions
22
    def self.encryptiontypes
23
      ["MD5","SSHA","CLEAR"]
24
    end
25
  end
19 26
end
app/models/auth_source_ldap.rb
17 17

  
18 18
require 'net/ldap'
19 19
require 'iconv'
20
require 'digest'
21
require 'base64'
20 22

  
21 23
class AuthSourceLdap < AuthSource 
22 24
  validates_presence_of :host, :port, :attr_login
......
24 26
  validates_length_of :account, :base_dn, :maximum => 255, :allow_nil => true
25 27
  validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true
26 28
  validates_numericality_of :port, :only_integer => true
27
  
28 29
  before_validation :strip_ldap_attributes
29 30
  
30 31
  def after_initialize
31
    self.port = 389 if self.port == 0
32
    self.port = 389 if self.port == 0 
32 33
  end
33 34
  
34 35
  def authenticate(login, password)
......
54 55
  def auth_method_name
55 56
    "LDAP"
56 57
  end
58

  
59
  def allow_password_changes?
60
    return self.enabled_passwd
61
  end
62
  
63
  def encode_password(clear_password)
64
    chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
65
    salt = ''
66
    10.times { |i| salt << chars[rand(chars.size-1)] }
67
    
68
    if self.password_encryption == "MD5"
69
      logger.debug "Encode as md5"
70
      return "{MD5}"+Base64.encode64(Digest::MD5.digest(clear_password)).chomp!
71
    end
72
    if self.password_encryption == "SSHA"
73
       logger.debug "Encode as ssha"
74
      return "{SSHA}"+Base64.encode64(Digest::SHA1.digest(clear_password+salt)+salt).chomp!
75
    end
76
    
77
    if self.password_encryption == "CLEAR"
78
       logger.debug "Encode as cleartype"
79
      return clear_password
80
    end
81
  end
57 82
  
83
  # change password
84
  def change_password(login,password,newPassword)
85
    begin
86
      attrs = get_user_dn(login)
87
      if attrs
88
        if self.account.blank? || self.account_password.blank?
89
          logger.debug "Binding with user account"
90
          ldap_con = initialize_ldap_con(attrs[:dn], password)
91
        else
92
          logger.debug "Binding with administrator account"
93
          ldap_con = initialize_ldap_con(self.account, self.account_password)
94
        end
95
        return ldap_con.replace_attribute attrs[:dn], :userPassword, encode_password(newPassword)
96
      end
97
    rescue
98
      return false
99
    end
100
    return false
101
  end
102
    
58 103
  private
59 104
  
60 105
  def strip_ldap_attributes
app/models/user.rb
332 332
    anonymous_user
333 333
  end
334 334
  
335
  def isExternal?
336
    return auth_source_id.present?
337
  end
338
  
339
  def changeExternalPassword(password,newPassword,newPasswordConfirm)
340
    return false if newPassword == "" || newPassword.length < 4
341
    return false if newPassword != newPasswordConfirm
342
    if (self.isExternal?)
343
      return self.auth_source.change_password(self.login,password,newPassword)
344
    end
345
    return false
346
  end
347
  
335 348
  protected
336 349
  
337 350
  def validate
app/views/ldap_auth_sources/_form.rhtml
25 25

  
26 26
<p><label for="auth_source_onthefly_register"><%=l(:field_onthefly)%></label>
27 27
<%= check_box 'auth_source', 'onthefly_register' %></p>
28
<p><label for="auth_source_enabled_passwd"><%=l(:field_enabled_passwd)%></label>
29
<%= check_box 'auth_source', 'enabled_passwd' %></p>
28 30
</div>
29 31

  
30 32
<fieldset class="box"><legend><%=l(:label_attribute_plural)%></legend>
......
39 41

  
40 42
<p><label for="auth_source_attr_mail"><%=l(:field_mail)%></label>
41 43
<%= text_field 'auth_source', 'attr_mail', :size => 20  %></p>
44

  
45
<p><label for="auth_source_password_encryption"><%=l(:field_password_encryption)%></label>
46
<%= select 'auth_source', 'password_encryption', AuthSourcesHelper::Encryption.encryptiontypes %>
47
</p>
42 48
</fieldset>
43 49
<!--[eoform:auth_source]-->
44 50

  
config/locales/de.yml
150 150
  general_pdf_encoding: ISO-8859-1
151 151
  general_first_day_of_week: '1'
152 152

  
153
  notice_external_password_error: Externes Konto konnte nicht aktualisiert werden.
153 154
  notice_account_updated: Konto wurde erfolgreich aktualisiert.
154 155
  notice_account_invalid_creditentials: Benutzer oder Kennwort ist ungültig.
155 156
  notice_account_password_updated: Kennwort wurde erfolgreich aktualisiert.
156 157
  notice_account_wrong_password: Falsches Kennwort.
157 158
  notice_account_register_done: Konto wurde erfolgreich angelegt.
158 159
  notice_account_unknown_email: Unbekannter Benutzer.
159
  notice_can_t_change_password: Dieses Konto verwendet eine externe Authentifizierungs-Quelle. Unmöglich, das Kennwort zu ändern.
160
  notice_can_t_change_password: Kennwort ändern ist gesperrt für diese externe Authentifizierungs-Quelle.
160 161
  notice_account_lost_email_sent: Eine E-Mail mit Anweisungen, ein neues Kennwort zu wählen, wurde Ihnen geschickt.
161 162
  notice_account_activated: Ihr Konto ist aktiviert. Sie können sich jetzt anmelden.
162 163
  notice_successful_create: Erfolgreich angelegt
......
273 274
  field_attr_lastname: Name-Attribut
274 275
  field_attr_mail: E-Mail-Attribut
275 276
  field_onthefly: On-the-fly-Benutzererstellung
277
  field_password_encryption: Verschlüsselungsart
278
  field_enabled_passwd: Password ändern erlauben
276 279
  field_start_date: Beginn
277 280
  field_done_ratio: % erledigt
278 281
  field_auth_source: Authentifizierungs-Modus
config/locales/en.yml
127 127
  general_pdf_encoding: ISO-8859-1
128 128
  general_first_day_of_week: '7'
129 129
  
130
  notice_external_password_error: External password changing goes wrong
130 131
  notice_account_updated: Account was successfully updated.
131 132
  notice_account_invalid_creditentials: Invalid user or password
132 133
  notice_account_password_updated: Password was successfully updated.
......
253 254
  field_attr_lastname: Lastname attribute
254 255
  field_attr_mail: Email attribute
255 256
  field_onthefly: On-the-fly user creation
257
  field_password_encryption: Encyrption
258
  field_enabled_passwd: Enabled password changing
256 259
  field_start_date: Start
257 260
  field_done_ratio: % Done
258 261
  field_auth_source: Authentication mode
db/migrate/20100609104539_ldap_password_change.rb
1
class LdapPasswordChange < ActiveRecord::Migration
2
  def self.up
3
      add_column :auth_sources,  :password_encryption, :string, :default => "MD5", :null => false
4
      add_column :auth_sources,  :enabled_passwd, :boolean, :default => false, :null => false
5
  end
6

  
7
  def self.down
8
    remove_column :auth_sources, :password_encryption
9
    remove_column :auth_sources, :enabled_passwd
10
  end
11
end
(2-2/7)