|
@@ -199,7 +199,8 @@ public abstract class Server {
|
|
|
// in ObjectWritable to efficiently transmit arrays of primitives
|
|
|
// 6 : Made RPC payload header explicit
|
|
|
// 7 : Changed Ipc Connection Header to use Protocol buffers
|
|
|
- public static final byte CURRENT_VERSION = 7;
|
|
|
+ // 8 : SASL server always sends a final response
|
|
|
+ public static final byte CURRENT_VERSION = 8;
|
|
|
|
|
|
/**
|
|
|
* Initial and max size of response buffer
|
|
@@ -1220,8 +1221,8 @@ public abstract class Server {
|
|
|
AUDITLOG.warn(AUTH_FAILED_FOR + clientIP + ":" + attemptingUser);
|
|
|
throw e;
|
|
|
}
|
|
|
- if (replyToken == null && authMethod == AuthMethod.PLAIN) {
|
|
|
- // client needs at least response to know if it should use SIMPLE
|
|
|
+ if (saslServer.isComplete() && replyToken == null) {
|
|
|
+ // send final response for success
|
|
|
replyToken = new byte[0];
|
|
|
}
|
|
|
if (replyToken != null) {
|
|
@@ -1392,7 +1393,7 @@ public abstract class Server {
|
|
|
}
|
|
|
|
|
|
private AuthMethod initializeAuthContext(AuthMethod authMethod)
|
|
|
- throws IOException {
|
|
|
+ throws IOException, InterruptedException {
|
|
|
try {
|
|
|
if (enabledAuthMethods.contains(authMethod)) {
|
|
|
saslServer = createSaslServer(authMethod);
|
|
@@ -1425,8 +1426,7 @@ public abstract class Server {
|
|
|
}
|
|
|
|
|
|
private SaslServer createSaslServer(AuthMethod authMethod)
|
|
|
- throws IOException {
|
|
|
- SaslServer saslServer = null;
|
|
|
+ throws IOException, InterruptedException {
|
|
|
String hostname = null;
|
|
|
String saslProtocol = null;
|
|
|
CallbackHandler saslCallback = null;
|
|
@@ -1462,10 +1462,23 @@ public abstract class Server {
|
|
|
"Server does not support SASL " + authMethod);
|
|
|
}
|
|
|
|
|
|
- String mechanism = authMethod.getMechanismName();
|
|
|
- saslServer = Sasl.createSaslServer(
|
|
|
- mechanism, saslProtocol, hostname,
|
|
|
- SaslRpcServer.SASL_PROPS, saslCallback);
|
|
|
+ return createSaslServer(authMethod.getMechanismName(), saslProtocol,
|
|
|
+ hostname, saslCallback);
|
|
|
+ }
|
|
|
+
|
|
|
+ private SaslServer createSaslServer(final String mechanism,
|
|
|
+ final String protocol,
|
|
|
+ final String hostname,
|
|
|
+ final CallbackHandler callback
|
|
|
+ ) throws IOException, InterruptedException {
|
|
|
+ SaslServer saslServer = UserGroupInformation.getCurrentUser().doAs(
|
|
|
+ new PrivilegedExceptionAction<SaslServer>() {
|
|
|
+ @Override
|
|
|
+ public SaslServer run() throws SaslException {
|
|
|
+ return Sasl.createSaslServer(mechanism, protocol, hostname,
|
|
|
+ SaslRpcServer.SASL_PROPS, callback);
|
|
|
+ }
|
|
|
+ });
|
|
|
if (saslServer == null) {
|
|
|
throw new AccessControlException(
|
|
|
"Unable to find SASL server implementation for " + mechanism);
|