diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 0f75482a9a6..f0b141a0f5f 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -64,6 +64,9 @@ Release 2.0.3-alpha - Unreleased HADOOP-9009. Add SecurityUtil methods to get/set authentication method (daryn via bobby) + HADOOP-9010. Map UGI authenticationMethod to RPC authMethod (daryn via + bobby) + OPTIMIZATIONS HADOOP-8866. SampleQuantiles#query is O(N^2) instead of O(N). (Andrew Wang 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 5789b2c9427..b8a2bc034ea 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 @@ -69,6 +69,7 @@ import org.apache.hadoop.security.SaslRpcClient; import org.apache.hadoop.security.SaslRpcServer.AuthMethod; import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; import org.apache.hadoop.security.token.Token; import org.apache.hadoop.security.token.TokenIdentifier; import org.apache.hadoop.security.token.TokenInfo; @@ -293,8 +294,9 @@ public class Client { } if (token != null) { - authMethod = AuthMethod.DIGEST; + authMethod = AuthenticationMethod.TOKEN.getAuthMethod(); } else if (UserGroupInformation.isSecurityEnabled()) { + // eventually just use the ticket's authMethod authMethod = AuthMethod.KERBEROS; } else { authMethod = AuthMethod.SIMPLE; 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 2542ee6aefc..e5bcd175d7c 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 @@ -1485,11 +1485,11 @@ public abstract class Server { if (!useSasl) { user = protocolUser; if (user != null) { - user.setAuthenticationMethod(AuthMethod.SIMPLE.authenticationMethod); + user.setAuthenticationMethod(AuthMethod.SIMPLE); } } else { // user is authenticated - user.setAuthenticationMethod(authMethod.authenticationMethod); + user.setAuthenticationMethod(authMethod); //Now we check if this is a proxy user case. If the protocol user is //different from the 'user', it is a proxy user scenario. However, //this is not allowed if user authenticated with DIGEST. diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcServer.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcServer.java index 31718628f22..31b4c35dae2 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcServer.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcServer.java @@ -42,7 +42,6 @@ import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.ipc.Server; -import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; import org.apache.hadoop.security.token.SecretManager; import org.apache.hadoop.security.token.TokenIdentifier; import org.apache.hadoop.security.token.SecretManager.InvalidToken; @@ -137,20 +136,17 @@ public class SaslRpcServer { /** Authentication method */ @InterfaceStability.Evolving public static enum AuthMethod { - SIMPLE((byte) 80, "", AuthenticationMethod.SIMPLE), - KERBEROS((byte) 81, "GSSAPI", AuthenticationMethod.KERBEROS), - DIGEST((byte) 82, "DIGEST-MD5", AuthenticationMethod.TOKEN); + SIMPLE((byte) 80, ""), + KERBEROS((byte) 81, "GSSAPI"), + DIGEST((byte) 82, "DIGEST-MD5"); /** The code for this method. */ public final byte code; public final String mechanismName; - public final AuthenticationMethod authenticationMethod; - private AuthMethod(byte code, String mechanismName, - AuthenticationMethod authMethod) { + private AuthMethod(byte code, String mechanismName) { this.code = code; this.mechanismName = mechanismName; - this.authenticationMethod = authMethod; } private static final int FIRST_CODE = values()[0].code; diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java index cefe989ca11..42ff4033cd8 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java @@ -57,6 +57,7 @@ import org.apache.hadoop.metrics2.annotation.Metric; import org.apache.hadoop.metrics2.annotation.Metrics; import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; import org.apache.hadoop.metrics2.lib.MutableRate; +import org.apache.hadoop.security.SaslRpcServer.AuthMethod; import org.apache.hadoop.security.authentication.util.KerberosName; import org.apache.hadoop.security.authentication.util.KerberosUtil; import org.apache.hadoop.security.token.Token; @@ -1008,13 +1009,34 @@ public class UserGroupInformation { @InterfaceAudience.Public @InterfaceStability.Evolving public static enum AuthenticationMethod { - SIMPLE, - KERBEROS, - TOKEN, - CERTIFICATE, - KERBEROS_SSL, - PROXY; - } + // currently we support only one auth per method, but eventually a + // subtype is needed to differentiate, ex. if digest is token or ldap + SIMPLE(AuthMethod.SIMPLE), + KERBEROS(AuthMethod.KERBEROS), + TOKEN(AuthMethod.DIGEST), + CERTIFICATE(null), + KERBEROS_SSL(null), + PROXY(null); + + private final AuthMethod authMethod; + private AuthenticationMethod(AuthMethod authMethod) { + this.authMethod = authMethod; + } + + public AuthMethod getAuthMethod() { + return authMethod; + } + + public static AuthenticationMethod valueOf(AuthMethod authMethod) { + for (AuthenticationMethod value : values()) { + if (value.getAuthMethod() == authMethod) { + return value; + } + } + throw new IllegalArgumentException( + "no authentication method for " + authMethod); + } + }; /** * Create a proxy user using username of the effective user and the ugi of the @@ -1279,6 +1301,15 @@ public class UserGroupInformation { user.setAuthenticationMethod(authMethod); } + /** + * Sets the authentication method in the subject + * + * @param authMethod + */ + public void setAuthenticationMethod(AuthMethod authMethod) { + user.setAuthenticationMethod(AuthenticationMethod.valueOf(authMethod)); + } + /** * Get the authentication method from the subject * diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java index a1bbd984d14..ca5f6e82dd7 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java @@ -303,7 +303,6 @@ public class TestUserGroupInformation { assertSame(secret, ugi.getCredentials().getSecretKey(secretKey)); } - @SuppressWarnings("unchecked") // from Mockito mocks @Test public void testGetCredsNotSame() throws Exception { @@ -427,6 +426,18 @@ public class TestUserGroupInformation { assertEquals(2, otherSet.size()); } + @Test + public void testTestAuthMethod() throws Exception { + UserGroupInformation ugi = UserGroupInformation.getCurrentUser(); + // verify the reverse mappings works + for (AuthenticationMethod am : AuthenticationMethod.values()) { + if (am.getAuthMethod() != null) { + ugi.setAuthenticationMethod(am.getAuthMethod()); + assertEquals(am, ugi.getAuthenticationMethod()); + } + } + } + @Test public void testUGIAuthMethod() throws Exception { final UserGroupInformation ugi = UserGroupInformation.getCurrentUser();