浏览代码

HADOOP-6649. login object in UGI should be inside the subject (jnp via boryas)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@951618 13f79535-47bb-0310-9956-ffa450edef68
Boris Shkolnik 15 年之前
父节点
当前提交
56b15e9e8f

+ 2 - 0
CHANGES.txt

@@ -65,6 +65,8 @@ Trunk (unreleased changes)
     glob pattern code less restrictive and more POSIX standard
     glob pattern code less restrictive and more POSIX standard
     compliant. (Luke Lu via eli)
     compliant. (Luke Lu via eli)
 
 
+    HADOOP-6649.  login object in UGI should be inside the subject (jnp via boryas)
+
 Release 0.21.0 - Unreleased
 Release 0.21.0 - Unreleased
 
 
   INCOMPATIBLE CHANGES
   INCOMPATIBLE CHANGES

+ 22 - 2
src/java/org/apache/hadoop/security/User.java

@@ -19,6 +19,8 @@ package org.apache.hadoop.security;
 
 
 import java.security.Principal;
 import java.security.Principal;
 
 
+import javax.security.auth.login.LoginContext;
+
 import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
 import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
 
 
 /**
 /**
@@ -29,12 +31,13 @@ class User implements Principal {
   private final String fullName;
   private final String fullName;
   private final String shortName;
   private final String shortName;
   private AuthenticationMethod authMethod = null;
   private AuthenticationMethod authMethod = null;
+  private LoginContext login = null;
 
 
   public User(String name) {
   public User(String name) {
-    this(name, null);
+    this(name, null, null);
   }
   }
   
   
-  public User(String name, AuthenticationMethod authMethod) {
+  public User(String name, AuthenticationMethod authMethod, LoginContext login) {
     fullName = name;
     fullName = name;
     int atIdx = name.indexOf('@');
     int atIdx = name.indexOf('@');
     if (atIdx == -1) {
     if (atIdx == -1) {
@@ -48,6 +51,7 @@ class User implements Principal {
       }
       }
     }
     }
     this.authMethod = authMethod;
     this.authMethod = authMethod;
+    this.login = login;
   }
   }
 
 
   /**
   /**
@@ -94,4 +98,20 @@ class User implements Principal {
   public AuthenticationMethod getAuthenticationMethod() {
   public AuthenticationMethod getAuthenticationMethod() {
     return authMethod;
     return authMethod;
   }
   }
+  
+  /**
+   * Returns login object
+   * @return login
+   */
+  public LoginContext getLogin() {
+    return login;
+  }
+  
+  /**
+   * Set the login object
+   * @param login
+   */
+  public void setLogin(LoginContext login) {
+    this.login = login;
+  }
 }
 }

+ 17 - 4
src/java/org/apache/hadoop/security/UserGroupInformation.java

@@ -206,8 +206,6 @@ public class UserGroupInformation {
 
 
   private final Subject subject;
   private final Subject subject;
   
   
-  private LoginContext login;
-  
   private static final String OS_LOGIN_MODULE_NAME;
   private static final String OS_LOGIN_MODULE_NAME;
   private static final Class<? extends Principal> OS_PRINCIPAL_CLASS;
   private static final Class<? extends Principal> OS_PRINCIPAL_CLASS;
   private static final boolean windows = 
   private static final boolean windows = 
@@ -330,6 +328,19 @@ public class UserGroupInformation {
       return null;
       return null;
     }
     }
   }
   }
+  
+  private LoginContext getLogin() {
+    for (User p: subject.getPrincipals(User.class)) {
+      return p.getLogin();
+    }
+    return null;
+  }
+  
+  private void setLogin(LoginContext login) {
+    for (User p: subject.getPrincipals(User.class)) {
+      p.setLogin(login);
+    }
+  }
 
 
   /**
   /**
    * Create a UserGroupInformation for the given subject.
    * Create a UserGroupInformation for the given subject.
@@ -371,7 +382,7 @@ public class UserGroupInformation {
               subject);
               subject);
         }
         }
         login.login();
         login.login();
-        loginUser.login = login;
+        loginUser.setLogin(login);
         loginUser = new UserGroupInformation(login.getSubject());
         loginUser = new UserGroupInformation(login.getSubject());
         String tokenFile = System.getenv(HADOOP_TOKEN_FILE_LOCATION);
         String tokenFile = System.getenv(HADOOP_TOKEN_FILE_LOCATION);
         if (tokenFile != null && isSecurityEnabled()) {
         if (tokenFile != null && isSecurityEnabled()) {
@@ -407,7 +418,7 @@ public class UserGroupInformation {
         new LoginContext(HadoopConfiguration.KEYTAB_KERBEROS_CONFIG_NAME, subject);
         new LoginContext(HadoopConfiguration.KEYTAB_KERBEROS_CONFIG_NAME, subject);
       login.login();
       login.login();
       loginUser = new UserGroupInformation(subject);
       loginUser = new UserGroupInformation(subject);
-      loginUser.login = login;
+      loginUser.setLogin(login);
     } catch (LoginException le) {
     } catch (LoginException le) {
       throw new IOException("Login failure for " + user + " from keytab " + 
       throw new IOException("Login failure for " + user + " from keytab " + 
                             path, le);
                             path, le);
@@ -427,6 +438,7 @@ public class UserGroupInformation {
   throws IOException {
   throws IOException {
     if (!isSecurityEnabled())
     if (!isSecurityEnabled())
       return;
       return;
+    LoginContext login = getLogin();
     if (login == null || keytabFile == null) {
     if (login == null || keytabFile == null) {
       throw new IOException("loginUserFromKeyTab must be done first");
       throw new IOException("loginUserFromKeyTab must be done first");
     }
     }
@@ -452,6 +464,7 @@ public class UserGroupInformation {
             getSubject());
             getSubject());
       LOG.info("Initiating re-login for " + keytabPrincipal);
       LOG.info("Initiating re-login for " + keytabPrincipal);
       login.login();
       login.login();
+      setLogin(login);
     } catch (LoginException le) {
     } catch (LoginException le) {
       throw new IOException("Login failure for " + keytabPrincipal + 
       throw new IOException("Login failure for " + keytabPrincipal + 
           " from keytab " + keytabFile, le);
           " from keytab " + keytabFile, le);

+ 15 - 0
src/test/core/org/apache/hadoop/security/TestUserGroupInformation.java

@@ -32,6 +32,8 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.List;
 import java.util.List;
 
 
+import javax.security.auth.login.LoginContext;
+
 import junit.framework.Assert;
 import junit.framework.Assert;
 
 
 import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
 import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
@@ -287,4 +289,17 @@ public class TestUserGroupInformation {
         "proxyAnother", realugi);
         "proxyAnother", realugi);
     Assert.assertEquals(proxyUgi3, proxyUgi4);
     Assert.assertEquals(proxyUgi3, proxyUgi4);
   }
   }
+  
+  @Test
+  public void testLoginObjectInSubject() throws Exception {
+    UserGroupInformation loginUgi = UserGroupInformation.getLoginUser();
+    UserGroupInformation anotherUgi = new UserGroupInformation(loginUgi
+        .getSubject());
+    LoginContext login1 = loginUgi.getSubject().getPrincipals(User.class)
+        .iterator().next().getLogin();
+    LoginContext login2 = anotherUgi.getSubject().getPrincipals(User.class)
+    .iterator().next().getLogin();
+    //login1 and login2 must be same instances
+    Assert.assertTrue(login1 == login2);
+  }
 }
 }