LDAP Auth Fails for Users in Many Groups

SonarQube: 7.9.2 (build 30863)
LDAP Plugin: 2.2 (build 608)

I have SonarQube deployed as a container in Kubernetes using the Oteemo helm chart.

For some users, LDAP is working fine. They log in; I see the user created in the admin users page. For others, they get a failure message and can’t log in. The user is never created in SQ. and I see a Null Pointer Exception in web.log.

I think this is related to groups. The users who can’t log in are in a lot of groups, and some debug logs (below) lead me to think this. As you can see the NPE happens before groups are returned in the 2nd example.

Here is the relevent sonar config:

sonar.security.realm=LDAP
sonar.authenticator.downcase=false
ldap.url=ldaps://ldap-mn.CompanyRedacted.com:636
ldap.bindDn=CN=BindAccountRedacted,OU=Service Accounts,OU=InfoSec,ou=corp,DC=CompanyRedacted,dc=com
ldap.bindPassword=REDCACTED
ldap.authentication=simple
ldap.user.baseDn=ou=cache,o=application
ldap.user.request=(&(objectClass=user)(sAMAccountName={login}))
ldap.user.realNameAttribute=name
ldap.user.emailAttribute=mail
ldap.group.baseDn=ou=cache,o=application
ldap.group.request=(&(objectClass=group)(member={dn}))
ldap.group.idAttribute=sAMAccountName

As a workaround I can remove the ldap.group.* properties. Then these users can log in but we’re unable to assign roles based on group membership.

Is there a way to configure a higher timeout for the group query? What else might I look at?

Logs for a user experiencing success:

2020.08.03 19:54:37 DEBUG web[AXOqT9N+r2HiqVPyADOM][o.s.p.l.LdapUsersProvider] Requesting details for user UserRedacted
2020.08.03 19:54:37 DEBUG web[AXOqT9N+r2HiqVPyADOM][o.s.p.l.LdapSearch] Search: LdapSearch{baseDn=ou=cache,o=application, scope=subtree, request=(&(objectClass=user)(sAMAccountName={0})), parameters=[UserRedacted], attributes=[mail, name]}
2020.08.03 19:54:37 DEBUG web[AXOqT9N+r2HiqVPyADOM][o.s.p.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=CN=BindAccountRedacted,OU=Service Accounts,OU=InfoSec,ou=corp,DC=CompanyRedacted,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap-mn.CompanyRedacted.com:636, java.naming.security.authentication=simple}
2020.08.03 19:54:37 DEBUG web[AXOqT9N+r2HiqVPyADOM][o.s.p.l.LdapSearch] Search: LdapSearch{baseDn=ou=cache,o=application, scope=subtree, request=(&(objectClass=user)(sAMAccountName={0})), parameters=[UserRedacted], attributes=null}
2020.08.03 19:54:37 DEBUG web[AXOqT9N+r2HiqVPyADOM][o.s.p.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=CN=BindAccountRedacted,OU=Service Accounts,OU=InfoSec,ou=corp,DC=CompanyRedacted,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap-mn.CompanyRedacted.com:636, java.naming.security.authentication=simple}
2020.08.03 19:54:37 DEBUG web[AXOqT9N+r2HiqVPyADOM][o.s.p.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=CN=Last\, First (000000),OU=People,ou=corp,ou=cache,o=application, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap-mn.CompanyRedacted.com:636, java.naming.security.authentication=simple}
2020.08.03 19:54:37 DEBUG web[AXOqT9N+r2HiqVPyADOM][o.s.p.l.LdapGroupsProvider] Requesting groups for user UserRedacted
2020.08.03 19:54:37 DEBUG web[AXOqT9N+r2HiqVPyADOM][o.s.p.l.LdapSearch] Search: LdapSearch{baseDn=ou=cache,o=application, scope=subtree, request=(&(objectClass=user)(sAMAccountName={0})), parameters=[UserRedacted], attributes=[dn]}
2020.08.03 19:54:37 DEBUG web[AXOqT9N+r2HiqVPyADOM][o.s.p.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=CN=BindAccountRedacted,OU=Service Accounts,OU=InfoSec,ou=corp,DC=CompanyRedacted,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap-mn.CompanyRedacted.com:636, java.naming.security.authentication=simple}
2020.08.03 19:54:37 DEBUG web[AXOqT9N+r2HiqVPyADOM][o.s.p.l.LdapSearch] Search: LdapSearch{baseDn=ou=cache,o=application, scope=subtree, request=(&(objectClass=group)(member={0})), parameters=[CN=Last\, First (000000),OU=People,ou=corp,ou=cache,o=application], attributes=[sAMAccountName]}
2020.08.03 19:54:37 DEBUG web[AXOqT9N+r2HiqVPyADOM][o.s.p.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=CN=BindAccountRedacted,OU=Service Accounts,OU=InfoSec,ou=corp,DC=CompanyRedacted,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap-mn.CompanyRedacted.com:636, java.naming.security.authentication=simple}
2020.08.03 19:54:37 DEBUG web[AXOqT9N+r2HiqVPyADOM][o.s.s.a.UserRegistrarImpl] List of groups returned by the identity provider '[Group_1, Group_2, Group_3]'
2020.08.03 19:54:37 DEBUG web[AXOqT9N+r2HiqVPyADOM][auth.event] login success [method|FORM][provider|REALM|LDAP][IP|10.42.8.0|192.168.7.245][login|UserRedacted]

Logs for a user experiencing failure:

2020.08.03 19:50:40 DEBUG web[AXOqT9N+r2HiqVPyADNh][o.s.p.l.LdapUsersProvider] Requesting details for user UserRedacted
2020.08.03 19:50:40 DEBUG web[AXOqT9N+r2HiqVPyADNh][o.s.p.l.LdapSearch] Search: LdapSearch{baseDn=ou=cache,o=application, scope=subtree, request=(&(objectClass=user)(sAMAccountName={0})), parameters=[UserRedacted], attributes=[mail, name]}
2020.08.03 19:50:40 DEBUG web[AXOqT9N+r2HiqVPyADNh][o.s.p.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=CN=BindAccountRedacted,OU=Service Accounts,OU=InfoSec,ou=corp,DC=CompanyRedacted,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap-mn.CompanyRedacted.com:636, java.naming.security.authentication=simple}
2020.08.03 19:50:40 DEBUG web[AXOqT9N+r2HiqVPyADNh][o.s.p.l.LdapSearch] Search: LdapSearch{baseDn=ou=cache,o=application, scope=subtree, request=(&(objectClass=user)(sAMAccountName={0})), parameters=[UserRedacted], attributes=null}
2020.08.03 19:50:40 DEBUG web[AXOqT9N+r2HiqVPyADNh][o.s.p.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=CN=BindAccountRedacted,OU=Service Accounts,OU=InfoSec,ou=corp,DC=CompanyRedacted,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap-mn.CompanyRedacted.com:636, java.naming.security.authentication=simple}
2020.08.03 19:50:40 DEBUG web[AXOqT9N+r2HiqVPyADNh][o.s.p.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=CN=Last\, First (000000),OU=People,ou=corp,ou=cache,o=application, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap-mn.CompanyRedacted.com:636, java.naming.security.authentication=simple}
2020.08.03 19:50:40 DEBUG web[AXOqT9N+r2HiqVPyADNh][o.s.p.l.LdapGroupsProvider] Requesting groups for user UserRedacted
2020.08.03 19:50:40 DEBUG web[AXOqT9N+r2HiqVPyADNh][o.s.p.l.LdapSearch] Search: LdapSearch{baseDn=ou=cache,o=application, scope=subtree, request=(&(objectClass=user)(sAMAccountName={0})), parameters=[UserRedacted], attributes=[dn]}
2020.08.03 19:50:40 DEBUG web[AXOqT9N+r2HiqVPyADNh][o.s.p.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=CN=BindAccountRedacted,OU=Service Accounts,OU=InfoSec,ou=corp,DC=CompanyRedacted,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap-mn.CompanyRedacted.com:636, java.naming.security.authentication=simple}
2020.08.03 19:50:40 DEBUG web[AXOqT9N+r2HiqVPyADNh][o.s.p.l.LdapSearch] Search: LdapSearch{baseDn=ou=cache,o=application, scope=subtree, request=(&(objectClass=group)(member={0})), parameters=[CN=Last\, First (000000),OU=People,ou=corp,ou=cache,o=application], attributes=[sAMAccountName]}
2020.08.03 19:50:40 DEBUG web[AXOqT9N+r2HiqVPyADNh][o.s.p.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=CN=BindAccountRedacted,OU=Service Accounts,OU=InfoSec,ou=corp,DC=CompanyRedacted,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap-mn.CompanyRedacted.com:636, java.naming.security.authentication=simple}
2020.08.03 19:50:40 ERROR web[AXOqT9N+r2HiqVPyADNh][o.s.s.a.CredentialsExternalAuthentication] Error during authentication
java.lang.NullPointerException: null
	at org.sonar.plugins.ldap.LdapGroupsProvider.mapGroups(LdapGroupsProvider.java:138)
	at org.sonar.plugins.ldap.LdapGroupsProvider.getGroups(LdapGroupsProvider.java:79)
	at org.sonar.plugins.ldap.LdapGroupsProvider.doGetGroups(LdapGroupsProvider.java:57)
	at org.sonar.server.authentication.CredentialsExternalAuthentication.synchronize(CredentialsExternalAuthentication.java:143)
	at org.sonar.server.authentication.CredentialsExternalAuthentication.doAuthenticate(CredentialsExternalAuthentication.java:114)
	at org.sonar.server.authentication.CredentialsExternalAuthentication.authenticate(CredentialsExternalAuthentication.java:91)
	at org.sonar.server.authentication.CredentialsAuthentication.authenticate(CredentialsAuthentication.java:66)
	at org.sonar.server.authentication.CredentialsAuthentication.authenticate(CredentialsAuthentication.java:54)
	at org.sonar.server.authentication.ws.LoginAction.authenticate(LoginAction.java:121)
	at org.sonar.server.authentication.ws.LoginAction.doFilter(LoginAction.java:100)
	at org.sonar.server.platform.web.MasterServletFilter$GodFilterChain.doFilter(MasterServletFilter.java:126)
	at org.sonar.server.platform.web.MasterServletFilter.doFilter(MasterServletFilter.java:95)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.sonar.server.user.UserSessionFilter.doFilter(UserSessionFilter.java:87)
	at org.sonar.server.user.UserSessionFilter.doFilter(UserSessionFilter.java:71)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.sonar.server.platform.web.CacheControlFilter.doFilter(CacheControlFilter.java:76)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.sonar.server.platform.web.SecurityServletFilter.doHttpFilter(SecurityServletFilter.java:76)
	at org.sonar.server.platform.web.SecurityServletFilter.doFilter(SecurityServletFilter.java:48)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.sonar.server.platform.web.RedirectFilter.doFilter(RedirectFilter.java:58)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.sonar.server.platform.web.requestid.RequestIdFilter.doFilter(RequestIdFilter.java:63)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.sonar.server.platform.web.RootFilter.doFilter(RootFilter.java:62)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:109)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	at ch.qos.logback.access.tomcat.LogbackValve.invoke(LogbackValve.java:256)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Unknown Source)
2020.08.03 19:50:40 DEBUG web[AXOqT9N+r2HiqVPyADNh][auth.event] login failure [cause|][method|FORM][provider|REALM|LDAP][IP|10.42.8.0|192.168.7.245][login|UserRedacted]

Hey @switchboardOp,

Could you check in web.log is there anything similar to this log INFO: Group mapping: {} but with actual content? (ideally whole web.log could be helpful with debug log enabled)

It seems like some groups were found in ldap, but SQ has failed to map it with user groups.

Apart from having a lot of groups is there anything different for such users?