|
@@ -19,6 +19,7 @@ package org.apache.hadoop.security;
|
|
|
|
|
|
import static org.apache.hadoop.fs.CommonConfigurationKeys.HADOOP_USER_GROUP_METRICS_PERCENTILES_INTERVALS;
|
|
|
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_TOKEN_FILES;
|
|
|
+import static org.apache.hadoop.security.UGIExceptionMessages.*;
|
|
|
import static org.apache.hadoop.util.PlatformName.IBM_JAVA;
|
|
|
|
|
|
import java.io.File;
|
|
@@ -743,8 +744,11 @@ public class UserGroupInformation {
|
|
|
ugi.setAuthenticationMethod(AuthenticationMethod.KERBEROS);
|
|
|
return ugi;
|
|
|
} catch (LoginException le) {
|
|
|
- throw new IOException("failure to login using ticket cache file " +
|
|
|
- ticketCache, le);
|
|
|
+ KerberosAuthException kae =
|
|
|
+ new KerberosAuthException(FAILURE_TO_LOGIN, le);
|
|
|
+ kae.setUser(user);
|
|
|
+ kae.setTicketCacheFile(ticketCache);
|
|
|
+ throw kae;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -753,16 +757,17 @@ public class UserGroupInformation {
|
|
|
*
|
|
|
* @param user The KerberosPrincipal to use in UGI
|
|
|
*
|
|
|
- * @throws IOException if the kerberos login fails
|
|
|
+ * @throws IOException
|
|
|
+ * @throws KerberosAuthException if the kerberos login fails
|
|
|
*/
|
|
|
public static UserGroupInformation getUGIFromSubject(Subject subject)
|
|
|
throws IOException {
|
|
|
if (subject == null) {
|
|
|
- throw new IOException("Subject must not be null");
|
|
|
+ throw new KerberosAuthException(SUBJECT_MUST_NOT_BE_NULL);
|
|
|
}
|
|
|
|
|
|
if (subject.getPrincipals(KerberosPrincipal.class).isEmpty()) {
|
|
|
- throw new IOException("Provided Subject must contain a KerberosPrincipal");
|
|
|
+ throw new KerberosAuthException(SUBJECT_MUST_CONTAIN_PRINCIPAL);
|
|
|
}
|
|
|
|
|
|
KerberosPrincipal principal =
|
|
@@ -882,7 +887,7 @@ public class UserGroupInformation {
|
|
|
loginUser.spawnAutoRenewalThreadForUserCreds();
|
|
|
} catch (LoginException le) {
|
|
|
LOG.debug("failure to login", le);
|
|
|
- throw new IOException("failure to login: " + le, le);
|
|
|
+ throw new KerberosAuthException(FAILURE_TO_LOGIN, le);
|
|
|
}
|
|
|
if (LOG.isDebugEnabled()) {
|
|
|
LOG.debug("UGI loginUser:"+loginUser);
|
|
@@ -989,7 +994,8 @@ public class UserGroupInformation {
|
|
|
* file and logs them in. They become the currently logged-in user.
|
|
|
* @param user the principal name to load from the keytab
|
|
|
* @param path the path to the keytab file
|
|
|
- * @throws IOException if the keytab file can't be read
|
|
|
+ * @throws IOException
|
|
|
+ * @throws KerberosAuthException if it's a kerberos login exception.
|
|
|
*/
|
|
|
@InterfaceAudience.Public
|
|
|
@InterfaceStability.Evolving
|
|
@@ -1018,8 +1024,10 @@ public class UserGroupInformation {
|
|
|
if (start > 0) {
|
|
|
metrics.loginFailure.add(Time.now() - start);
|
|
|
}
|
|
|
- throw new IOException("Login failure for " + user + " from keytab " +
|
|
|
- path+ ": " + le, le);
|
|
|
+ KerberosAuthException kae = new KerberosAuthException(LOGIN_FAILURE, le);
|
|
|
+ kae.setUser(user);
|
|
|
+ kae.setKeytabFile(path);
|
|
|
+ throw kae;
|
|
|
}
|
|
|
LOG.info("Login successful for user " + keytabPrincipal
|
|
|
+ " using keytab file " + keytabFile);
|
|
@@ -1030,8 +1038,9 @@ public class UserGroupInformation {
|
|
|
* This method assumes that the user logged in by calling
|
|
|
* {@link #loginUserFromKeytab(String, String)}.
|
|
|
*
|
|
|
- * @throws IOException if a failure occurred in logout, or if the user did
|
|
|
- * not log in by invoking loginUserFromKeyTab() before.
|
|
|
+ * @throws IOException
|
|
|
+ * @throws KerberosAuthException if a failure occurred in logout,
|
|
|
+ * or if the user did not log in by invoking loginUserFromKeyTab() before.
|
|
|
*/
|
|
|
@InterfaceAudience.Public
|
|
|
@InterfaceStability.Evolving
|
|
@@ -1042,7 +1051,7 @@ public class UserGroupInformation {
|
|
|
}
|
|
|
LoginContext login = getLogin();
|
|
|
if (login == null || keytabFile == null) {
|
|
|
- throw new IOException("loginUserFromKeytab must be done first");
|
|
|
+ throw new KerberosAuthException(MUST_FIRST_LOGIN_FROM_KEYTAB);
|
|
|
}
|
|
|
|
|
|
try {
|
|
@@ -1053,9 +1062,10 @@ public class UserGroupInformation {
|
|
|
login.logout();
|
|
|
}
|
|
|
} catch (LoginException le) {
|
|
|
- throw new IOException("Logout failure for " + user + " from keytab " +
|
|
|
- keytabFile + ": " + le,
|
|
|
- le);
|
|
|
+ KerberosAuthException kae = new KerberosAuthException(LOGOUT_FAILURE, le);
|
|
|
+ kae.setUser(user.toString());
|
|
|
+ kae.setKeytabFile(keytabFile);
|
|
|
+ throw kae;
|
|
|
}
|
|
|
|
|
|
LOG.info("Logout successful for user " + keytabPrincipal
|
|
@@ -1066,6 +1076,7 @@ public class UserGroupInformation {
|
|
|
* Re-login a user from keytab if TGT is expired or is close to expiry.
|
|
|
*
|
|
|
* @throws IOException
|
|
|
+ * @throws KerberosAuthException if it's a kerberos login exception.
|
|
|
*/
|
|
|
public synchronized void checkTGTAndReloginFromKeytab() throws IOException {
|
|
|
if (!isSecurityEnabled()
|
|
@@ -1087,12 +1098,12 @@ public class UserGroupInformation {
|
|
|
* happened already.
|
|
|
* The Subject field of this UserGroupInformation object is updated to have
|
|
|
* the new credentials.
|
|
|
- * @throws IOException on a failure
|
|
|
+ * @throws IOException
|
|
|
+ * @throws KerberosAuthException on a failure
|
|
|
*/
|
|
|
@InterfaceAudience.Public
|
|
|
@InterfaceStability.Evolving
|
|
|
- public synchronized void reloginFromKeytab()
|
|
|
- throws IOException {
|
|
|
+ public synchronized void reloginFromKeytab() throws IOException {
|
|
|
if (!isSecurityEnabled() ||
|
|
|
user.getAuthenticationMethod() != AuthenticationMethod.KERBEROS ||
|
|
|
!isKeytab)
|
|
@@ -1112,7 +1123,7 @@ public class UserGroupInformation {
|
|
|
|
|
|
LoginContext login = getLogin();
|
|
|
if (login == null || keytabFile == null) {
|
|
|
- throw new IOException("loginUserFromKeyTab must be done first");
|
|
|
+ throw new KerberosAuthException(MUST_FIRST_LOGIN_FROM_KEYTAB);
|
|
|
}
|
|
|
|
|
|
long start = 0;
|
|
@@ -1144,8 +1155,10 @@ public class UserGroupInformation {
|
|
|
if (start > 0) {
|
|
|
metrics.loginFailure.add(Time.now() - start);
|
|
|
}
|
|
|
- throw new IOException("Login failure for " + keytabPrincipal +
|
|
|
- " from keytab " + keytabFile + ": " + le, le);
|
|
|
+ KerberosAuthException kae = new KerberosAuthException(LOGIN_FAILURE, le);
|
|
|
+ kae.setPrincipal(keytabPrincipal);
|
|
|
+ kae.setKeytabFile(keytabFile);
|
|
|
+ throw kae;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1154,19 +1167,19 @@ public class UserGroupInformation {
|
|
|
* method assumes that login had happened already.
|
|
|
* The Subject field of this UserGroupInformation object is updated to have
|
|
|
* the new credentials.
|
|
|
- * @throws IOException on a failure
|
|
|
+ * @throws IOException
|
|
|
+ * @throws KerberosAuthException on a failure
|
|
|
*/
|
|
|
@InterfaceAudience.Public
|
|
|
@InterfaceStability.Evolving
|
|
|
- public synchronized void reloginFromTicketCache()
|
|
|
- throws IOException {
|
|
|
+ public synchronized void reloginFromTicketCache() throws IOException {
|
|
|
if (!isSecurityEnabled() ||
|
|
|
user.getAuthenticationMethod() != AuthenticationMethod.KERBEROS ||
|
|
|
!isKrbTkt)
|
|
|
return;
|
|
|
LoginContext login = getLogin();
|
|
|
if (login == null) {
|
|
|
- throw new IOException("login must be done first");
|
|
|
+ throw new KerberosAuthException(MUST_FIRST_LOGIN);
|
|
|
}
|
|
|
long now = Time.now();
|
|
|
if (!hasSufficientTimeElapsed(now)) {
|
|
@@ -1193,8 +1206,9 @@ public class UserGroupInformation {
|
|
|
login.login();
|
|
|
setLogin(login);
|
|
|
} catch (LoginException le) {
|
|
|
- throw new IOException("Login failure for " + getUserName() + ": " + le,
|
|
|
- le);
|
|
|
+ KerberosAuthException kae = new KerberosAuthException(LOGIN_FAILURE, le);
|
|
|
+ kae.setUser(getUserName());
|
|
|
+ throw kae;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1240,8 +1254,10 @@ public class UserGroupInformation {
|
|
|
if (start > 0) {
|
|
|
metrics.loginFailure.add(Time.now() - start);
|
|
|
}
|
|
|
- throw new IOException("Login failure for " + user + " from keytab " +
|
|
|
- path + ": " + le, le);
|
|
|
+ KerberosAuthException kae = new KerberosAuthException(LOGIN_FAILURE, le);
|
|
|
+ kae.setUser(user);
|
|
|
+ kae.setKeytabFile(path);
|
|
|
+ throw kae;
|
|
|
} finally {
|
|
|
if(oldKeytabFile != null) keytabFile = oldKeytabFile;
|
|
|
if(oldKeytabPrincipal != null) keytabPrincipal = oldKeytabPrincipal;
|