HADOOP6638. try to relogin in a case of failed RPC connection (expired tgt) only in case the subject is loginUser or proxyUgi.realUser.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@948523 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
73643f4211
commit
a7aacdc2d6
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue