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 405549af6df..80eea84ec61 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 @@ -1598,7 +1598,10 @@ private void saslProcess(RpcSaslProto saslMessage) String qop = (String) saslServer.getNegotiatedProperty(Sasl.QOP); // SASL wrapping is only used if the connection has a QOP, and // the value is not auth. ex. auth-int & auth-priv - useWrap = (qop != null && !"auth".equalsIgnoreCase(qop)); + useWrap = (qop != null && !"auth".equalsIgnoreCase(qop)); + if (!useWrap) { + disposeSasl(); + } } } @@ -1692,9 +1695,9 @@ private RpcSaslProto processSaslToken(RpcSaslProto saslMessage) private void switchToSimple() { // disable SASL and blank out any SASL server authProtocol = AuthProtocol.NONE; - saslServer = null; + disposeSasl(); } - + private RpcSaslProto buildSaslResponse(SaslState state, byte[] replyToken) { if (LOG.isDebugEnabled()) { LOG.debug("Will send " + state + " token of size " @@ -1731,6 +1734,8 @@ private void disposeSasl() { try { saslServer.dispose(); } catch (SaslException ignored) { + } finally { + saslServer = null; } } } @@ -1980,7 +1985,7 @@ private void processConnectionContext(DataInputStream dis) .getProtocol() : null; UserGroupInformation protocolUser = ProtoUtil.getUgi(connectionContext); - if (saslServer == null) { + if (authProtocol == AuthProtocol.NONE) { user = protocolUser; } else { // user is authenticated 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 ec53e8c9762..72371a7ae91 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 @@ -28,6 +28,7 @@ import org.apache.hadoop.fs.CommonConfigurationKeysPublic; import org.apache.hadoop.io.Text; import org.apache.hadoop.ipc.Client.ConnectionId; +import org.apache.hadoop.ipc.Server.Connection; import org.apache.hadoop.net.NetUtils; import org.apache.hadoop.security.*; import org.apache.hadoop.security.SaslRpcServer.AuthMethod; @@ -270,7 +271,16 @@ private void doDigestRpc(Server server, TestTokenSecretManager sm) assertEquals(TOKEN, authMethod); //QOP must be auth assertEquals(expectedQop.saslQop, - RPC.getConnectionIdForProxy(proxy).getSaslQop()); + RPC.getConnectionIdForProxy(proxy).getSaslQop()); + int n = 0; + for (Connection connection : server.getConnections()) { + // only qop auth should dispose of the sasl server + boolean hasServer = (connection.saslServer != null); + assertTrue("qop:" + expectedQop + " hasServer:" + hasServer, + (expectedQop == QualityOfProtection.AUTHENTICATION) ^ hasServer); + n++; + } + assertTrue(n > 0); proxy.ping(null, newEmptyRequest()); } finally { stop(server, proxy);