Defect #35135

FrozenError when new LDAP users try to login

Added by Diego Maniero 5 months ago. Updated 5 months ago.

Status:ClosedStart date:
Priority:NormalDue date:
Assignee:Go MAEDA% Done:

0%

Category:Accounts / authentication
Target version:4.2.1
Resolution:Fixed Affected version:4.2.0

Description

Using the official docker image I recently updated from 4.0.3 to 4.2.0, no plugins installed (anymore).
Database is on mysql:5.7

Since then new accounts and some existing users (2 out of 30) authenticating using LDAP started having issues logging in. Internal accounts work fine.
LDAP authentication works fine for everyone else.

@I, [2021-04-20T15:46:52.874309 #1]  INFO -- : Completed 500 Internal Server Error in 22ms (ActiveRecord: 3.1ms),
F, [2021-04-20T15:46:52.875489 #1] FATAL -- :   ,
F, [2021-04-20T15:46:52.875538 #1] FATAL -- : FrozenError (can't modify frozen String: ""):,
F, [2021-04-20T15:46:52.875567 #1] FATAL -- :   ,
F, [2021-04-20T15:46:52.875601 #1] FATAL -- : app/models/auth_source_ldap.rb:250:in `force_encoding',
                    app/models/auth_source_ldap.rb:250:in `get_attr',
                    app/models/auth_source_ldap.rb:199:in `get_user_attributes_from_ldap_entry',
                    app/models/auth_source_ldap.rb:236:in `block in get_user_dn',
                    app/models/auth_source_ldap.rb:232:in `get_user_dn',
                    app/models/auth_source_ldap.rb:59:in `block in authenticate',
                    app/models/auth_source_ldap.rb:144:in `block in with_timeout',
                    app/models/auth_source_ldap.rb:143:in `with_timeout',
                    app/models/auth_source_ldap.rb:58:in `authenticate',
                    app/models/user.rb:344:in `check_password?',
                    app/models/user.rb:244:in `try_to_login!',
                    app/controllers/account_controller.rb:311:in `password_authentication',
                    app/controllers/account_controller.rb:306:in `authenticate_user',
                    app/controllers/account_controller.rb:40:in `login',
                    lib/redmine/sudo_mode.rb:61:in `sudo_mode',@

35135-test.diff Magnifier (756 Bytes) Go MAEDA, 2021-04-21 07:37


Related issues

Related to Redmine - Feature #31500: Ruby 2.7 support Closed

Associated revisions

Revision 20966
Added by Go MAEDA 5 months ago

Ruby 2.7: FrozenError when new LDAP users try to login (#35135).

Patch by Pavel Rosický.

Revision 20967
Added by Go MAEDA 5 months ago

Merged r20966 from trunk to 4.2-stable (#35135).

History

#1 Updated by Marius BALTEANU 5 months ago

  • Description updated (diff)
  • Status changed from New to Confirmed
  • Target version set to 4.1.3

The following change should fix this issue:

diff --git a/app/models/auth_source_ldap.rb b/app/models/auth_source_ldap.rb
index 623359531..fd5f89582 100644
--- a/app/models/auth_source_ldap.rb
+++ b/app/models/auth_source_ldap.rb
@@ -247,7 +247,7 @@ class AuthSourceLdap < AuthSource
     def get_attr(entry, attr_name)
       if !attr_name.blank?
         value = entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
-        value.to_s.force_encoding('UTF-8')
+        value.dup.to_s.force_encoding('UTF-8')
       end
     end
   end

#3 Updated by Go MAEDA 5 months ago

#4 Updated by Go MAEDA 5 months ago

According to #35135#note-2, the error occurs when Ruby version is 2.7 or higher. If so, I don't think it's necessary to backport this fix to 4.1-stable that does not support Ruby 2.7.

#5 Updated by Go MAEDA 5 months ago

Go MAEDA wrote:

According to #35135#note-2, the error occurs when Ruby version is 2.7 or higher. If so, I don't think it's necessary to backport this fix to 4.1-stable that does not support Ruby 2.7.

Sorry, I withdraw my previous comment. The fix should also be backported to 4.1-stable. Even when using Ruby 2.5, auth_source_ldap_test.rb updated by 35135-test.diff causes FrozenError.

Error:
AuthSourceLdapTest#test_get_attr:
FrozenError: can't modify frozen String
    app/models/auth_source_ldap.rb:250:in `force_encoding'
    app/models/auth_source_ldap.rb:250:in `get_attr'
    test/unit/auth_source_ldap_test.rb:93:in `test_get_attr'

rails test test/unit/auth_source_ldap_test.rb:85

#6 Updated by Pavel Rosický 5 months ago

Even when using Ruby 2.5, auth_source_ldap_test.rb updated by 35135-test.diff causes FrozenError

attr strings in your test scenario are frozen due to # frozen_string_literal: true pragma. In reality, it should affect Ruby 2.7+ only and only if the attribute doesn't exist AuthSourceLdap.get_attr(attr, 'invalid_attr_name') which leads to a case nil.to_s which is frozen on Ruby 2.7, but not on previous versions.

looking at the Marius patch, I think it doesn't fix the error because

nil.dup.to_s.frozen? is still true

we should duplicate the string after the conversion

value.to_s.dup.force_encoding('UTF-8')

or even better like this

(+value.to_s).force_encoding('UTF-8')

#7 Updated by Marius BALTEANU 5 months ago

Pavel Rosický wrote:

looking at the Marius patch, I think it doesn't fix the error because
[...]

You're right, thanks for pointing this out.

Lets fix this by using any of the fixes proposed by Pavel.

#8 Updated by Go MAEDA 5 months ago

  • Subject changed from FrozenError when new ldap users try to login. to FrozenError when new LDAP users try to login
  • Status changed from Confirmed to Closed
  • Assignee set to Go MAEDA
  • Target version changed from 4.1.3 to 4.2.1
  • Resolution set to Fixed

Committed the fix. Thank you all for your contribution.

Also available in: Atom PDF