Uploaded image for project: 'Confluence Data Center'
  1. Confluence Data Center
  2. CONFSERVER-25022

Changing username case in LDAP causes external group memberships to disappear

    XMLWordPrintable

Details

    Description

      Tested in Confluence 3.5.13 and Confluence 4.1.7. If a user name in LDAP has the case changed, the connector recognizes the change (and notes it in the log that it can't update the username), then proceeds to run an update against the membership table that fails, throwing this error and removing affected users' memberships in the database to their external LDAP groups:

      2012-03-23 17:40:50,917 INFO [http-8090-2] [embedded.admin.list.DirectoriesController] sync User directory synchronisation requested: [ LDAP server ], type: [ CONNECTOR ]
      2012-03-23 17:40:50,951 INFO [scheduler_Worker-5] [atlassian.crowd.directory.DbCachingRemoteDirectory] synchroniseCache synchronisation for directory [ 98306 ] starting
      2012-03-23 17:40:50,969 INFO [scheduler_Worker-5] [directory.ldap.cache.RemoteDirectoryCacheRefresher] findAllRemoteUsers found [ 6 ] remote users in [ 16ms ]
      2012-03-23 17:40:50,982 INFO [scheduler_Worker-5] [atlassian.crowd.directory.DbCachingRemoteChangeOperations] getUsersToAddAndUpdate scanning [ 6 ] users to add or update
      2012-03-23 17:40:50,983 WARN [scheduler_Worker-5] [atlassian.crowd.directory.DbCachingRemoteChangeOperations] getUsersToAddAndUpdate remote username [ CeltY ] casing differs from local username [ celty ]. User details will be kept updated, but the username cannot be updated
      2012-03-23 17:40:50,984 INFO [scheduler_Worker-5] [atlassian.crowd.directory.DirectoryCacheImplUsingChangeOperations] addOrUpdateCachedUsers scanned and compared [ 6 ] users for update in DB cache in [ 8ms ]
      2012-03-23 17:40:50,985 INFO [scheduler_Worker-5] [atlassian.crowd.directory.DirectoryCacheImplUsingChangeOperations] addOrUpdateCachedUsers synchronised [ 6 ] users in [ 10ms ]
      2012-03-23 17:40:50,986 INFO [scheduler_Worker-5] [atlassian.crowd.directory.DbCachingRemoteChangeOperations] deleteCachedUsersNotIn scanned and compared [ 6 ] users for delete in DB cache in [ 1ms ]
      2012-03-23 17:40:50,987 INFO [scheduler_Worker-5] [atlassian.crowd.directory.DbCachingRemoteChangeOperations] deleteCachedUsersNotIn scanned for deleted users in [ 2ms ]
      2012-03-23 17:40:51,003 INFO [scheduler_Worker-5] [directory.ldap.cache.RemoteDirectoryCacheRefresher] findAllRemoteGroups found [ 2 ] remote groups in [ 16ms ]
      2012-03-23 17:40:51,004 INFO [scheduler_Worker-5] [atlassian.crowd.directory.DirectoryCacheImplUsingChangeOperations] addOrUpdateCachedGroups scanning [ 2 ] groups to add or update
      2012-03-23 17:40:51,009 INFO [scheduler_Worker-5] [atlassian.crowd.directory.DbCachingRemoteChangeOperations] findGroupsToUpdate scanned and compared [ 2 ] groups for update in DB cache in [ 5ms ]
      2012-03-23 17:40:51,011 INFO [scheduler_Worker-5] [atlassian.crowd.directory.DirectoryCacheImplUsingChangeOperations] addOrUpdateCachedGroups synchronized [ 2 ] groups in [ 7ms ]
      2012-03-23 17:40:51,017 INFO [scheduler_Worker-5] [atlassian.crowd.directory.DbCachingRemoteChangeOperations] deleteCachedGroupsNotIn scanned and compared [ 2 ] groups for delete in DB cache in [ 5ms ]
      2012-03-23 17:40:51,040 INFO [scheduler_Worker-5] [directory.ldap.cache.AbstractCacheRefresher] synchroniseMemberships found [ 0 ] remote user-group memberships, [ 0 ] remote group-group memberships in [ 11ms ]
      2012-03-23 17:40:51,048 INFO [scheduler_Worker-5] [directory.ldap.cache.AbstractCacheRefresher] synchroniseMemberships Migrated memberships for [1] of [2] groups
      2012-03-23 17:40:51,107 INFO [scheduler_Worker-5] [directory.ldap.cache.AbstractCacheRefresher] synchroniseMemberships found [ 3 ] remote user-group memberships, [ 0 ] remote group-group memberships in [ 58ms ]
      2012-03-23 17:40:51,256 ERROR [scheduler_Worker-5] [sf.hibernate.util.JDBCExceptionReporter] logExceptions ERROR: duplicate key value violates unique constraint "cwd_unique_user_membership"
      2012-03-23 17:40:51,258 ERROR [scheduler_Worker-5] [sf.hibernate.impl.SessionImpl] execute Could not synchronize database state with session
      2012-03-23 17:40:51,282 WARN [scheduler_Worker-5] [persistence.hibernate.batch.AbstractBatchProcessor] processBatch batch failed falling back to individual processing
      java.lang.RuntimeException: could not flush session
      	at com.atlassian.crowd.embedded.hibernate2.batch.Hibernate2BatchProcessor.flushSession(Hibernate2BatchProcessor.java:169)
      	at com.atlassian.crowd.embedded.hibernate2.batch.Hibernate2BatchProcessor.commitTransaction(Hibernate2BatchProcessor.java:107)
      	at com.atlassian.crowd.embedded.hibernate2.batch.Hibernate2BatchProcessor.afterProcessBatch(Hibernate2BatchProcessor.java:42)
      	at com.atlassian.crowd.util.persistence.hibernate.batch.AbstractBatchProcessor.processBatch(AbstractBatchProcessor.java:160)
      	at com.atlassian.crowd.util.persistence.hibernate.batch.AbstractBatchProcessor.execute(AbstractBatchProcessor.java:132)
      	at com.atlassian.crowd.embedded.hibernate2.HibernateMembershipDao.addAll(HibernateMembershipDao.java:201)
      	at com.atlassian.crowd.embedded.hibernate2.HibernateMembershipDao.addAllUsersToGroup(HibernateMembershipDao.java:59)
      	at com.atlassian.confluence.user.crowd.CachedCrowdMembershipDao.addAllUsersToGroup(CachedCrowdMembershipDao.java:100)
      	at com.atlassian.crowd.directory.CachingDirectory.addAllUsersToGroup(CachingDirectory.java:125)
      	at com.atlassian.crowd.directory.DbCachingRemoteChangeOperations.addUserMembershipsForGroup(DbCachingRemoteChangeOperations.java:750)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:597)
      	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
      	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
      	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
      	at com.atlassian.crowd.directory.$Proxy976.addUserMembershipsForGroup(Unknown Source)
      	at com.atlassian.crowd.directory.DirectoryCacheImplUsingChangeOperations.syncUserMembersForGroup(DirectoryCacheImplUsingChangeOperations.java:116)
      	at com.atlassian.crowd.directory.ldap.cache.AbstractCacheRefresher.synchroniseMemberships(AbstractCacheRefresher.java:155)
      	at com.atlassian.crowd.directory.ldap.cache.AbstractCacheRefresher.synchroniseAll(AbstractCacheRefresher.java:44)
      	at com.atlassian.crowd.directory.DbCachingRemoteDirectory.synchroniseCache(DbCachingRemoteDirectory.java:619)
      	at com.atlassian.crowd.manager.directory.DirectorySynchroniserImpl.synchronise(DirectorySynchroniserImpl.java:63)
      	at com.atlassian.crowd.directory.DbCachingDirectoryPoller.pollChanges(DbCachingDirectoryPoller.java:50)
      	at com.atlassian.crowd.manager.directory.monitor.poller.DirectoryPollerJobBean.executeInternal(DirectoryPollerJobBean.java:29)
      	at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:86)
      	at org.quartz.core.JobRunShell.run(JobRunShell.java:199)
      	at com.atlassian.confluence.schedule.quartz.ConfluenceQuartzThreadPool$1.run(ConfluenceQuartzThreadPool.java:20)
      	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)
      Caused by: net.sf.hibernate.exception.ConstraintViolationException: could not insert: [com.atlassian.crowd.embedded.hibernate2.HibernateMembership#294918]
      	at net.sf.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:62)
      	at net.sf.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:29)
      	at net.sf.hibernate.persister.AbstractEntityPersister.convert(AbstractEntityPersister.java:1331)
      	at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:472)
      	at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:436)
      	at net.sf.hibernate.impl.ScheduledInsertion.execute(ScheduledInsertion.java:37)
      	at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2447)
      	at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2433)
      	at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2390)
      	at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2259)
      	at com.atlassian.crowd.embedded.hibernate2.batch.Hibernate2BatchProcessor.flushSession(Hibernate2BatchProcessor.java:165)
      	... 31 more
      Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "cwd_unique_user_membership"
      	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
      	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
      	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
      	at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:500)
      	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
      	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:334)
      	at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
      	at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
      	at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:462)
      	... 38 more
      

      My guess is that there's a dirty transaction going on and the cwd_membership/row. One transaction deletes data from the tables, and the other attempts to insert, but the row still exists in it's transaction that was created prior to the delete committing.

      Fix

      Change the case of the username back to what it was in the source system. This must match the case in Confluence to avoid these sync issues.

      Workaround

      Forcing a sync, or waiting for the automatic task, will restore the membership to the table as there is no longer a row to conflict with in the cwd_membership table.

      Secondary Workaround

      If the preceding workaround does not work please try enacting the following steps to force remove all the of the groups.

      1. Login to Confluence admin
      2. Turn off naive DN matching
      3. Perform full directory sync
      4. Turned on naive DN matching
      5. Perform full directory sync

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              alaskowski Adam Laskowski (Inactive)
              Votes:
              3 Vote for this issue
              Watchers:
              10 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: