diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Client.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Client.java index ae3999b775..4a0b5aec40 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Client.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Client.java @@ -18,6 +18,7 @@ package org.apache.hadoop.ipc; +import org.apache.hadoop.security.AccessControlException; import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.hadoop.thirdparty.com.google.common.base.Preconditions; import org.apache.hadoop.thirdparty.com.google.common.util.concurrent.ThreadFactoryBuilder; @@ -857,7 +858,8 @@ public AuthMethod run() } } else if (UserGroupInformation.isSecurityEnabled()) { if (!fallbackAllowed) { - throw new IOException("Server asks us to fall back to SIMPLE " + + throw new AccessControlException( + "Server asks us to fall back to SIMPLE " + "auth, but this client is configured to only allow secure " + "connections."); } diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java index cbee1234ec..9be4ff2e93 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java @@ -2202,7 +2202,7 @@ private void doSaslReply(Message message) throws IOException { private void doSaslReply(Exception ioe) throws IOException { setupResponse(authFailedCall, RpcStatusProto.FATAL, RpcErrorCodeProto.FATAL_UNAUTHORIZED, - null, ioe.getClass().getName(), ioe.toString()); + null, ioe.getClass().getName(), ioe.getMessage()); sendResponse(authFailedCall); } @@ -2597,8 +2597,7 @@ private void processOneRpc(ByteBuffer bb) final RpcCall call = new RpcCall(this, callId, retry); setupResponse(call, rse.getRpcStatusProto(), rse.getRpcErrorCodeProto(), null, - t.getClass().getName(), - t.getMessage() != null ? t.getMessage() : t.toString()); + t.getClass().getName(), t.getMessage()); sendResponse(call); } } diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetUtils.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetUtils.java index 2b2c028552..0f4dd9d897 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetUtils.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetUtils.java @@ -46,6 +46,7 @@ import javax.net.SocketFactory; +import org.apache.hadoop.security.AccessControlException; import org.apache.hadoop.thirdparty.com.google.common.cache.Cache; import org.apache.hadoop.thirdparty.com.google.common.cache.CacheBuilder; @@ -874,6 +875,11 @@ public static IOException wrapException(final String destHost, + " failed on socket exception: " + exception + ";" + see("SocketException")); + } else if (exception instanceof AccessControlException) { + return wrapWithMessage(exception, + "Call From " + + localHost + " to " + destHost + ":" + destPort + + " failed: " + exception.getMessage()); } else { // 1. Return instance of same type with exception msg if Exception has a // String constructor. diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java index 5f94457465..72085a19ec 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java @@ -533,13 +533,16 @@ public void handle(Callback[] callbacks) } private static Pattern BadToken = - Pattern.compile(".*DIGEST-MD5: digest response format violation.*"); + Pattern.compile("^" + RemoteException.class.getName() + + "\\("+ SaslException.class.getName() + "\\): " + + "DIGEST-MD5: digest response format violation.*"); private static Pattern KrbFailed = Pattern.compile(".*Failed on local exception:.* " + "Failed to specify server's Kerberos principal name.*"); private static Pattern Denied(AuthMethod method) { - return Pattern.compile(".*RemoteException.*AccessControlException.*: " - + method + " authentication is not enabled.*"); + return Pattern.compile("^" + RemoteException.class.getName() + + "\\(" + AccessControlException.class.getName() + "\\): " + + method + " authentication is not enabled.*"); } private static Pattern No(AuthMethod ... method) { String methods = StringUtils.join(method, ",\\s*"); @@ -547,10 +550,10 @@ private static Pattern No(AuthMethod ... method) { "Client cannot authenticate via:\\[" + methods + "\\].*"); } private static Pattern NoTokenAuth = - Pattern.compile(".*IllegalArgumentException: " + + Pattern.compile("^" + IllegalArgumentException.class.getName() + ": " + "TOKEN authentication requires a secret manager"); private static Pattern NoFallback = - Pattern.compile(".*Failed on local exception:.* " + + Pattern.compile("^" + AccessControlException.class.getName() + ":.* " + "Server asks us to fall back to SIMPLE auth, " + "but this client is configured to only allow secure connections.*");