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);


Reply via email to