You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by bo...@apache.org on 2010/05/26 20:29:30 UTC

svn commit: r948523 - in /hadoop/common/trunk: CHANGES.txt src/java/org/apache/hadoop/ipc/Client.java src/java/org/apache/hadoop/security/UserGroupInformation.java

Author: boryas
Date: Wed May 26 18:29:30 2010
New Revision: 948523

URL: http://svn.apache.org/viewvc?rev=948523&view=rev
Log:
HADOOP6638. try to relogin in a case of failed RPC connection (expired tgt) only in case the subject is loginUser or proxyUgi.realUser.

Modified:
    hadoop/common/trunk/CHANGES.txt
    hadoop/common/trunk/src/java/org/apache/hadoop/ipc/Client.java
    hadoop/common/trunk/src/java/org/apache/hadoop/security/UserGroupInformation.java

Modified: hadoop/common/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/CHANGES.txt?rev=948523&r1=948522&r2=948523&view=diff
==============================================================================
--- hadoop/common/trunk/CHANGES.txt (original)
+++ hadoop/common/trunk/CHANGES.txt Wed May 26 18:29:30 2010
@@ -28,8 +28,10 @@ Trunk (unreleased changes)
     (Patrick Angeles via cdouglas)
 
   BUG FIXES
+    HADOOP-6638. try to relogin in a case of failed RPC connection (expired tgt) 
+    only in case the subject is loginUser or proxyUgi.realUser. (boryas)
 
-    HADOOP-6781. security audit log shouldn't have exception in it.
+    HADOOP-6781. security audit log shouldn't have exception in it. (boryas)
 
     HADOOP-6612.  Protocols RefreshUserToGroupMappingsProtocol and 
     RefreshAuthorizationPolicyProtocol will fail with security enabled (boryas)

Modified: hadoop/common/trunk/src/java/org/apache/hadoop/ipc/Client.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/src/java/org/apache/hadoop/ipc/Client.java?rev=948523&r1=948522&r2=948523&view=diff
==============================================================================
--- hadoop/common/trunk/src/java/org/apache/hadoop/ipc/Client.java (original)
+++ hadoop/common/trunk/src/java/org/apache/hadoop/ipc/Client.java Wed May 26 18:29:30 2010
@@ -377,26 +377,34 @@ public class Client {
             serverPrincipal);
         return saslRpcClient.saslConnect(in2, out2);
       } catch (javax.security.sasl.SaslException je) {
+        UserGroupInformation loginUser = UserGroupInformation.getLoginUser();
+        UserGroupInformation currentUser = UserGroupInformation.getCurrentUser();
+        UserGroupInformation realUser = currentUser.getRealUser();
         if (authMethod == AuthMethod.KERBEROS && 
-            UserGroupInformation.isLoginKeytabBased()) {
-          //try re-login
-          UserGroupInformation.getCurrentUser().reloginFromKeytab();
           //try setting up the connection again
+          UserGroupInformation.isLoginKeytabBased() &&
+          // relogin only in case it is the login user (e.g. JT)
+          // or superuser (like oozie).
+          ((currentUser != null && currentUser.equals(loginUser)) ||
+           (realUser != null && realUser.equals(loginUser)))) {
           try {
+            //try re-login
+            loginUser.reloginFromKeytab();
             disposeSasl();
             saslRpcClient = new SaslRpcClient(authMethod, token,
                 serverPrincipal);
             return saslRpcClient.saslConnect(in2, out2);
           } catch (javax.security.sasl.SaslException jee) {
-            UserGroupInformation.
-            setLastUnsuccessfulAuthenticationAttemptTime
-            (System.currentTimeMillis());
             LOG.warn("Couldn't setup connection for " + 
-                UserGroupInformation.getCurrentUser().getUserName() +
+                loginUser.getUserName() +
                 " to " + serverPrincipal + " even after relogin.");
             throw jee;
+          } catch (IOException ie) {
+            ie.initCause(je);
+            throw ie;
           }
-        } else throw je;
+        } 
+        throw je;
       }
     }
     /** Connect to the server and set up the I/O streams. It then sends

Modified: hadoop/common/trunk/src/java/org/apache/hadoop/security/UserGroupInformation.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/src/java/org/apache/hadoop/security/UserGroupInformation.java?rev=948523&r1=948522&r2=948523&view=diff
==============================================================================
--- hadoop/common/trunk/src/java/org/apache/hadoop/security/UserGroupInformation.java (original)
+++ hadoop/common/trunk/src/java/org/apache/hadoop/security/UserGroupInformation.java Wed May 26 18:29:30 2010
@@ -129,8 +129,6 @@ public class UserGroupInformation {
   private static boolean useKerberos;
   /** Server-side groups fetching service */
   private static Groups groups;
-  /** The last authentication time */
-  private static long lastUnsuccessfulAuthenticationAttemptTime;
   
   public static final long MIN_TIME_BEFORE_RELOGIN = 10 * 60 * 1000L;
   
@@ -138,6 +136,9 @@ public class UserGroupInformation {
   public static final String HADOOP_TOKEN_FILE_LOCATION = 
     "HADOOP_TOKEN_FILE_LOCATION";
   
+  /** The last relogin attempt */
+  private long lastReloginTime = 0;
+
   /** 
    * A method to initialize the fields that depend on a configuration.
    * Must be called before useKerberos or groups is used.
@@ -205,7 +206,7 @@ public class UserGroupInformation {
 
   private final Subject subject;
   
-  private static LoginContext login;
+  private LoginContext login;
   
   private static final String OS_LOGIN_MODULE_NAME;
   private static final Class<? extends Principal> OS_PRINCIPAL_CLASS;
@@ -359,12 +360,18 @@ public class UserGroupInformation {
   static UserGroupInformation getLoginUser() throws IOException {
     if (loginUser == null) {
       try {
+        Subject subject = new Subject();
+        loginUser = new UserGroupInformation(subject);
+        LoginContext login;
         if (isSecurityEnabled()) {
-          login = new LoginContext(HadoopConfiguration.USER_KERBEROS_CONFIG_NAME);
+          login = new LoginContext(HadoopConfiguration.USER_KERBEROS_CONFIG_NAME,
+              subject);
         } else {
-          login = new LoginContext(HadoopConfiguration.SIMPLE_CONFIG_NAME);
+          login = new LoginContext(HadoopConfiguration.SIMPLE_CONFIG_NAME, 
+              subject);
         }
         login.login();
+        loginUser.login = login;
         loginUser = new UserGroupInformation(login.getSubject());
         String tokenFile = System.getenv(HADOOP_TOKEN_FILE_LOCATION);
         if (tokenFile != null && isSecurityEnabled()) {
@@ -393,11 +400,14 @@ public class UserGroupInformation {
 
     keytabFile = path;
     keytabPrincipal = user;
+    Subject subject = new Subject();
+    LoginContext login; 
     try {
       login = 
-        new LoginContext(HadoopConfiguration.KEYTAB_KERBEROS_CONFIG_NAME);
+        new LoginContext(HadoopConfiguration.KEYTAB_KERBEROS_CONFIG_NAME, subject);
       login.login();
-      loginUser = new UserGroupInformation(login.getSubject());
+      loginUser = new UserGroupInformation(subject);
+      loginUser.login = login;
     } catch (LoginException le) {
       throw new IOException("Login failure for " + user + " from keytab " + 
                             path, le);
@@ -420,13 +430,15 @@ public class UserGroupInformation {
     if (login == null || keytabFile == null) {
       throw new IOException("loginUserFromKeyTab must be done first");
     }
-    if (System.currentTimeMillis() -lastUnsuccessfulAuthenticationAttemptTime <
-          MIN_TIME_BEFORE_RELOGIN) {
+    long now = System.currentTimeMillis();
+    if (now - lastReloginTime < MIN_TIME_BEFORE_RELOGIN ) {
       LOG.warn("Not attempting to re-login since the last re-login was " +
           "attempted less than " + (MIN_TIME_BEFORE_RELOGIN/1000) + " seconds"+
           " before.");
       return;
     }
+    // register most recent relogin
+    lastReloginTime = System.currentTimeMillis();
     try {
       LOG.info("Initiating logout for " + getUserName());
       //clear up the kerberos state. But the tokens are not cleared! As per 
@@ -446,11 +458,7 @@ public class UserGroupInformation {
     } 
   }
 
-  public synchronized static void 
-    setLastUnsuccessfulAuthenticationAttemptTime(long time) {
-    lastUnsuccessfulAuthenticationAttemptTime = time;
-  }
-  
+
   public synchronized static boolean isLoginKeytabBased() {
     return keytabFile != null;
   }