> On Nov. 22, 2016, 8:57 a.m., Sebastian Toader wrote:
> > ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java,
> > line 83
> > <https://reviews.apache.org/r/53959/diff/1/?file=1568079#file1568079line83>
> >
> > Why is this logged as warn and not debug ?
>
> Robert Levas wrote:
> I thought it was a severe enough issue to make a warning so we ensure it
> gets logged. The reason this is in a `LOG.isDebugEnabled` block is to
> provide more inforamation - the stack trace - when debugging is on. If
> debugging is not on, the same waringing is posted to the log, just no stack
> trace. I have been dinged on this before since it could make the log too
> wordy if we always posted the stack track.
How about something like this?
```
LOG.warn("Failed to communicate with the LDAP server: " + cause.getMessage());
LOG.debug(e);
```
- Sebastian
-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
https://reviews.apache.org/r/53959/#review156553
-----------------------------------------------------------
On Nov. 21, 2016, 7:43 p.m., Robert Levas wrote:
>
> -----------------------------------------------------------
> This is an automatically generated e-mail. To reply, visit:
> https://reviews.apache.org/r/53959/
> -----------------------------------------------------------
>
> (Updated Nov. 21, 2016, 7:43 p.m.)
>
>
> Review request for Ambari, Laszlo Puskas, Oliver Szabo, and Sebastian Toader.
>
>
> Bugs: AMBARI-18938
> https://issues.apache.org/jira/browse/AMBARI-18938
>
>
> Repository: ambari
>
>
> Description
> -------
>
> When authenticating using LDAP where the LDAP server is a Centrify LDAP
> proxy, a `NullPointerException` is being thrown due to unexpected missing
> LDAP user object attributes.
>
> ```
> 10 Nov 2016 08:23:38,789 ERROR [ambari-client-thread-25]
> AmbariLdapBindAuthenticator:95 - Caught exception
> java.lang.NullPointerException
> at
> org.apache.ambari.server.security.authorization.AmbariLdapBindAuthenticator.authenticate(AmbariLdapBindAuthenticator.java:83)
> at
> org.springframework.security.ldap.authentication.LdapAuthenticationProvider.doAuthentication(LdapAuthenticationProvider.java:178)
> at
> org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:61)
> at
> org.apache.ambari.server.security.authorization.AmbariLdapAuthenticationProvider.authenticate(AmbariLdapAuthenticationProvider.java:73)
> at
> org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
> at
> org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:168)
> at
> org.apache.ambari.server.security.authentication.AmbariAuthenticationFilter.doFilter(AmbariAuthenticationFilter.java:88)
> at
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
> at
> org.apache.ambari.server.security.authorization.AmbariUserAuthorizationFilter.doFilter(AmbariUserAuthorizationFilter.java:91)
> at
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
> at
> org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
> at
> org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
> at
> org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
> at
> org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
> at
> org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
> at
> org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
> at
> org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1478)
> at
> org.apache.ambari.server.api.MethodOverrideFilter.doFilter(MethodOverrideFilter.java:72)
> at
> org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1478)
> at
> org.apache.ambari.server.api.AmbariPersistFilter.doFilter(AmbariPersistFilter.java:47)
> at
> org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1478)
> at
> org.apache.ambari.server.security.AbstractSecurityHeaderFilter.doFilter(AbstractSecurityHeaderFilter.java:109)
> at
> org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1478)
> at
> org.eclipse.jetty.servlets.UserAgentFilter.doFilter(UserAgentFilter.java:82)
> at org.eclipse.jetty.servlets.GzipFilter.doFilter(GzipFilter.java:294)
> at
> org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1478)
> at
> org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:499)
> at
> org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
> at
> org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
> at
> org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
> at
> org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
> at
> org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:427)
> at
> org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
> at
> org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
> at
> org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
> at
> org.apache.ambari.server.controller.AmbariHandlerList.processHandlers(AmbariHandlerList.java:212)
> at
> org.apache.ambari.server.controller.AmbariHandlerList.processHandlers(AmbariHandlerList.java:201)
> at
> org.apache.ambari.server.controller.AmbariHandlerList.handle(AmbariHandlerList.java:139)
> at
> org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
> at org.eclipse.jetty.server.Server.handle(Server.java:370)
> at
> org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
> at
> org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:973)
> at
> org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1035)
> at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:641)
> at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:231)
> at
> org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
> at
> org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)
> at
> org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53)
> at
> org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
> at
> org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
> at java.lang.Thread.run(Thread.java:745)
> ```
>
> # Cause
> The cause for this `NPE` is related to missing data from the attribute search
> request made to a Centrify LDAP proxy after a bind has occurred. Since the
> query filter at this point is "`objectClass=*`", the Centrify LDAP proxy does
> not have enough data to determine what information to return to the caller.
> However, the filter was something like "`objectClass=posixAccount`", it will
> be able to build a set of attributes to return to the caller since it would
> determine that the call wants data for a specific _profile_.
>
> This can be seen by the following {{tcpdump}} entry:
> ```
> LDAPMessage searchRequest(2) "uid=user1,ou=people,ou=dev,dc=apache,dc=org"
> baseObject
> messageID: 2
> protocolOp: searchRequest (3)
> searchRequest
> baseObject: uid=user1,ou=people,ou=dev,dc=apache,dc=org
> scope: baseObject (0)
> derefAliases: derefAlways (3)
> sizeLimit: 0
> timeLimit: 0
> typesOnly: False
> Filter: (objectClass=*)
> attributes: 0 items
> [Response In: 2]
> controls: 1 item
> ```
>
> Note the filter line above: *`Filter: (objectClass=*)`*
>
> From the Centrify LDAP proxy logs, the following lines can be seen showing
> that no mapping is avaialbe:
>
> ```
> Nov 8 12:13:45 host1 slapd: cdc search start with filterstr: (objectClass=*)
> Nov 8 12:13:45 host1 slapd: cdc search: objectType = ( is mapped to NONE)
> Nov 8 12:13:45 host1 slapd: cdc search after translation filter =
> (objectClass=*)
> ```
>
> This search filter is hardcoded in `com.sun.jndi.ldap.LdapCtx` as seen in
> http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/com/sun/jndi/ldap/LdapCtx.java#1308.
>
> This code is invoked from the Spring LDAP library after attempting to
> authenticate using the Spring
> org.springframework.security.ldap.authentication.BindAuthenticator class.
>
> # Solution
> To solve this, Ambari should avoid using
> `org.springframework.security.ldap.authentication.BindAuthenticator` to
> authenticate users via LDAP so that more control can be had over when and how
> user attributes are obtained.
>
>
> Diffs
> -----
>
>
> ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java
> 6905757
>
> ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticator.java
> b34ef6a
>
> ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticatorTest.java
> cea4b66
>
> Diff: https://reviews.apache.org/r/53959/diff/
>
>
> Testing
> -------
>
> Manually tested against various LDAP servers.
>
>
> Thanks,
>
> Robert Levas
>
>