Uploaded image for project: 'Crowd Data Center'
  1. Crowd Data Center
  2. CWD-3683

"Unable to rename user" errors when attempting to login with a LDAP user

      Steps to reproduce

      1. Create a user with mixed case sensitivity such as "Horatio Nelson" in LDAP
      2. Hook Confluence to the LDAP directory via Internal with LDAP Authentication (Delegated)
      3. Login first as "Horatio Nelson" (to create the user as "Horatio Nelson" in the cwd_user table)
      4. Logout, then login again as "horatio nelson" (all lowercase)

      You will get this error in Confluence (JIRA is working fine, more about it below):

      2013-10-11 22:19:58,407 ERROR [http-8443-6] [[Standalone].[localhost].[/c530].[action]] log Servlet.service() for servlet action threw exception
      java.lang.IllegalStateException: Unable to rename user Horatio Nelson to horatio nelson
      	at com.atlassian.crowd.directory.AbstractInternalDirectory.forceRenameUser(AbstractInternalDirectory.java:611)
      	at com.atlassian.crowd.directory.DelegatedAuthenticationDirectory.authenticateAndUpdateOrCreate(DelegatedAuthenticationDirectory.java:218)
      	at com.atlassian.crowd.directory.DelegatedAuthenticationDirectory.authenticate(DelegatedAuthenticationDirectory.java:175)
      

      Cause:

      The problem is caused by this function in com.atlassian.crowd.directory.DelegatedAuthenticationDirectory.java:

      private User authenticateAndUpdateOrCreate(String name, PasswordCredential credential)
                  throws InactiveAccountException, ExpiredCredentialException, OperationFailedException, InvalidAuthenticationException, UserNotFoundException
          {
              // authenticate the user against LDAP
              User ldapUser = ldapDirectory.authenticate(name, credential);
              // Try to find the corresponding local user
              User internalUser = findLocalUserByExternalId(ldapUser.getExternalId());
              if (internalUser != null)
              {
                  if (!internalUser.getName().equals(name))
                  {
                      // We want to rename the existing user
                      if (isUserUpdateOnAuthEnabled())
                      {
                          // push any existing user out of our way and rename
                          try
                          {
                              internalUser = internalDirectory.forceRenameUser(internalUser, name);
                          }
                          catch (UserNotFoundException e)
                          {
                              // Pretty unlucky
                              throw new ConcurrentModificationException("Unable to rename '" + internalUser.getName() + "' to new name '" + name + "' during login.");
                          }
                      }
      

      Specifically, this if statement:

      if (!internalUser.getName().equals(name))
      

      Which takes the name string directly from the user input, and comparing it to the username stored in cwd_user directly, hence, the mismatch, which is why forceRenameUser is called in the first place

      So far, this affects any Confluence distribution bundled with the Crowd 2.7 integration libraries

      Description update:

            [CWD-3683] "Unable to rename user" errors when attempting to login with a LDAP user

            There are in fact one problem here which causes two different effects (in JIRA and Confluence). The source of the problem is that we compare the name given by user not the one we get from LDAP. Moreover we do the check without ignoring case. This causes forceRename to be called. From here we get two different behaviours as JIRA and Confluence have separete DAO impementations. In JIRA this unnecessary forced rename is overwritten down in the code while in Confluence it causes a problem we can see above. The fix for Crowd is to :

            • compare the right name
            • make a case-insensitive check in "if" statment

            This however does not solve the original problem which occurred in Confluence, just brings the code in Crowd on the right tracks.

            Michal Orzechowski (Inactive) added a comment - There are in fact one problem here which causes two different effects (in JIRA and Confluence). The source of the problem is that we compare the name given by user not the one we get from LDAP. Moreover we do the check without ignoring case. This causes forceRename to be called. From here we get two different behaviours as JIRA and Confluence have separete DAO impementations. In JIRA this unnecessary forced rename is overwritten down in the code while in Confluence it causes a problem we can see above. The fix for Crowd is to : compare the right name make a case-insensitive check in "if" statment This however does not solve the original problem which occurred in Confluence, just brings the code in Crowd on the right tracks.

              morzechowski Michal Orzechowski (Inactive)
              fsim Foo Sim (Inactive)
              Affected customers:
              9 This affects my team
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: