Author: daryn Date: Fri Aug 9 16:32:29 2013 New Revision: 1512382 URL: http://svn.apache.org/r1512382 Log: merge -c 1512381 FIXES: HADOOP-9789. Support server advertised kerberos principals (daryn)
Modified: hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/CHANGES.txt hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcClient.java hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcServer.java hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java Modified: hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/CHANGES.txt URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/CHANGES.txt?rev=1512382&r1=1512381&r2=1512382&view=diff ============================================================================== --- hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/CHANGES.txt (original) +++ hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/CHANGES.txt Fri Aug 9 16:32:29 2013 @@ -53,6 +53,8 @@ Release 2.1.0-beta - 2013-08-06 HADOOP-9821. ClientId should have getMsb/getLsb methods. (Tsuyoshi OZAWA via jing9) + HADOOP-9789. Support server advertised kerberos principals (daryn) + OPTIMIZATIONS BUG FIXES Modified: hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcClient.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcClient.java?rev=1512382&r1=1512381&r2=1512382&view=diff ============================================================================== --- hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcClient.java (original) +++ hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcClient.java Fri Aug 9 16:32:29 2013 @@ -33,6 +33,7 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.regex.Pattern; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; @@ -51,6 +52,7 @@ import org.apache.commons.logging.LogFac import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.GlobPattern; import org.apache.hadoop.ipc.ProtobufRpcEngine.RpcRequestMessageWrapper; import org.apache.hadoop.ipc.ProtobufRpcEngine.RpcResponseMessageWrapper; import org.apache.hadoop.ipc.RPC.RpcKind; @@ -280,9 +282,8 @@ public class SaslRpcClient { * @return String of the server's principal * @throws IOException - error determining configured principal */ - - // try to get the configured principal for the remote server - private String getServerPrincipal(SaslAuth authType) throws IOException { + @VisibleForTesting + String getServerPrincipal(SaslAuth authType) throws IOException { KerberosInfo krbInfo = SecurityUtil.getKerberosInfo(protocol, conf); LOG.debug("Get kerberos info proto:"+protocol+" info:"+krbInfo); if (krbInfo == null) { // protocol has no support for kerberos @@ -294,28 +295,37 @@ public class SaslRpcClient { "Can't obtain server Kerberos config key from protocol=" + protocol.getCanonicalName()); } - // construct the expected principal from the config - String confPrincipal = SecurityUtil.getServerPrincipal( - conf.get(serverKey), serverAddr.getAddress()); - if (confPrincipal == null || confPrincipal.isEmpty()) { - throw new IllegalArgumentException( - "Failed to specify server's Kerberos principal name"); - } - // ensure it looks like a host-based service principal - KerberosName name = new KerberosName(confPrincipal); - if (name.getHostName() == null) { - throw new IllegalArgumentException( - "Kerberos principal name does NOT have the expected hostname part: " - + confPrincipal); + // construct server advertised principal for comparision + String serverPrincipal = new KerberosPrincipal( + authType.getProtocol() + "/" + authType.getServerId()).getName(); + boolean isPrincipalValid = false; + + // use the pattern if defined + String serverKeyPattern = conf.get(serverKey + ".pattern"); + if (serverKeyPattern != null && !serverKeyPattern.isEmpty()) { + Pattern pattern = GlobPattern.compile(serverKeyPattern); + isPrincipalValid = pattern.matcher(serverPrincipal).matches(); + } else { + // check that the server advertised principal matches our conf + String confPrincipal = SecurityUtil.getServerPrincipal( + conf.get(serverKey), serverAddr.getAddress()); + if (confPrincipal == null || confPrincipal.isEmpty()) { + throw new IllegalArgumentException( + "Failed to specify server's Kerberos principal name"); + } + KerberosName name = new KerberosName(confPrincipal); + if (name.getHostName() == null) { + throw new IllegalArgumentException( + "Kerberos principal name does NOT have the expected hostname part: " + + confPrincipal); + } + isPrincipalValid = serverPrincipal.equals(confPrincipal); } - // check that the server advertised principal matches our conf - KerberosPrincipal serverPrincipal = new KerberosPrincipal( - authType.getProtocol() + "/" + authType.getServerId()); - if (!serverPrincipal.getName().equals(confPrincipal)) { + if (!isPrincipalValid) { throw new IllegalArgumentException( "Server has invalid Kerberos principal: " + serverPrincipal); } - return confPrincipal; + return serverPrincipal; } Modified: hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcServer.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcServer.java?rev=1512382&r1=1512381&r2=1512382&view=diff ============================================================================== --- hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcServer.java (original) +++ hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcServer.java Fri Aug 9 16:32:29 2013 @@ -47,7 +47,6 @@ import org.apache.hadoop.classification. import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.ipc.Server; import org.apache.hadoop.ipc.Server.Connection; -import org.apache.hadoop.security.authentication.util.KerberosName; import org.apache.hadoop.security.token.SecretManager; import org.apache.hadoop.security.token.TokenIdentifier; import org.apache.hadoop.security.token.SecretManager.InvalidToken; @@ -104,12 +103,12 @@ public class SaslRpcServer { String fullName = UserGroupInformation.getCurrentUser().getUserName(); if (LOG.isDebugEnabled()) LOG.debug("Kerberos principal name is " + fullName); - KerberosName krbName = new KerberosName(fullName); - serverId = krbName.getHostName(); - if (serverId == null) { - serverId = ""; - } - protocol = krbName.getServiceName(); + // don't use KerberosName because we don't want auth_to_local + String[] parts = fullName.split("[/@]", 2); + protocol = parts[0]; + // should verify service host is present here rather than in create() + // but lazy tests are using a UGI that isn't a SPN... + serverId = (parts.length < 2) ? "" : parts[1]; break; } default: Modified: hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java?rev=1512382&r1=1512381&r2=1512382&view=diff ============================================================================== --- hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java (original) +++ hadoop/common/branches/branch-2.1-beta/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java Fri Aug 9 16:32:29 2013 @@ -824,14 +824,13 @@ public class TestSaslRPC { final AuthMethod serverAuth, final UseToken tokenType) throws Exception { - String currentUser = UserGroupInformation.getCurrentUser().getUserName(); - final Configuration serverConf = new Configuration(conf); serverConf.set(HADOOP_SECURITY_AUTHENTICATION, serverAuth.toString()); UserGroupInformation.setConfiguration(serverConf); - final UserGroupInformation serverUgi = - UserGroupInformation.createRemoteUser(currentUser + "-SERVER/localhost@NONE"); + final UserGroupInformation serverUgi = (serverAuth == KERBEROS) + ? UserGroupInformation.createRemoteUser("server/localhost@NONE") + : UserGroupInformation.createRemoteUser("server"); serverUgi.setAuthenticationMethod(serverAuth); final TestTokenSecretManager sm = new TestTokenSecretManager(); @@ -866,7 +865,7 @@ public class TestSaslRPC { UserGroupInformation.setConfiguration(clientConf); final UserGroupInformation clientUgi = - UserGroupInformation.createRemoteUser(currentUser + "-CLIENT"); + UserGroupInformation.createRemoteUser("client"); clientUgi.setAuthenticationMethod(clientAuth); final InetSocketAddress addr = NetUtils.getConnectAddress(server);