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 su...@apache.org on 2016/10/08 00:21:10 UTC
[27/50] [abbrv] hadoop git commit: HADOOP-13627. Have an explicit
KerberosAuthException for UGI to throw,
text from public constants. Contributed by Xiao Chen.
HADOOP-13627. Have an explicit KerberosAuthException for UGI to throw, text from public constants. Contributed by Xiao Chen.
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/2e853be6
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/2e853be6
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/2e853be6
Branch: refs/heads/YARN-2915
Commit: 2e853be6577a5b98fd860e6d64f89ca6d160514a
Parents: 3565c9a
Author: Xiao Chen <xi...@apache.org>
Authored: Fri Oct 7 13:46:27 2016 -0700
Committer: Xiao Chen <xi...@apache.org>
Committed: Fri Oct 7 13:46:27 2016 -0700
----------------------------------------------------------------------
.../hadoop/security/KerberosAuthException.java | 118 +++++++++++++++++++
.../hadoop/security/UGIExceptionMessages.java | 46 ++++++++
.../hadoop/security/UserGroupInformation.java | 74 +++++++-----
3 files changed, 209 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hadoop/blob/2e853be6/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/KerberosAuthException.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/KerberosAuthException.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/KerberosAuthException.java
new file mode 100644
index 0000000..811c7c9
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/KerberosAuthException.java
@@ -0,0 +1,118 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.security;
+
+import static org.apache.hadoop.security.UGIExceptionMessages.*;
+
+import java.io.IOException;
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+
+/**
+ * Thrown when {@link UserGroupInformation} failed with an unrecoverable error,
+ * such as failure in kerberos login/logout, invalid subject etc.
+ *
+ * Caller should not retry when catching this exception.
+ */
+@InterfaceAudience.Public
+@InterfaceStability.Unstable
+public class KerberosAuthException extends IOException {
+ static final long serialVersionUID = 31L;
+
+ private String user;
+ private String principal;
+ private String keytabFile;
+ private String ticketCacheFile;
+ private String initialMessage;
+
+ public KerberosAuthException(String msg) {
+ super(msg);
+ }
+
+ public KerberosAuthException(Throwable cause) {
+ super(cause);
+ }
+
+ public KerberosAuthException(String initialMsg, Throwable cause) {
+ this(cause);
+ initialMessage = initialMsg;
+ }
+
+ public void setUser(final String u) {
+ user = u;
+ }
+
+ public void setPrincipal(final String p) {
+ principal = p;
+ }
+
+ public void setKeytabFile(final String k) {
+ keytabFile = k;
+ }
+
+ public void setTicketCacheFile(final String t) {
+ ticketCacheFile = t;
+ }
+
+ /** @return The initial message, or null if not set. */
+ public String getInitialMessage() {
+ return initialMessage;
+ }
+
+ /** @return The keytab file path, or null if not set. */
+ public String getKeytabFile() {
+ return keytabFile;
+ }
+
+ /** @return The principal, or null if not set. */
+ public String getPrincipal() {
+ return principal;
+ }
+
+ /** @return The ticket cache file path, or null if not set. */
+ public String getTicketCacheFile() {
+ return ticketCacheFile;
+ }
+
+ /** @return The user, or null if not set. */
+ public String getUser() {
+ return user;
+ }
+
+ @Override
+ public String getMessage() {
+ final StringBuilder sb = new StringBuilder();
+ if (initialMessage != null) {
+ sb.append(initialMessage);
+ }
+ if (user != null) {
+ sb.append(FOR_USER + user);
+ }
+ if (principal != null) {
+ sb.append(FOR_PRINCIPAL + principal);
+ }
+ if (keytabFile != null) {
+ sb.append(FROM_KEYTAB + keytabFile);
+ }
+ if (ticketCacheFile != null) {
+ sb.append(USING_TICKET_CACHE_FILE+ ticketCacheFile);
+ }
+ sb.append(" " + super.getMessage());
+ return sb.toString();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/hadoop/blob/2e853be6/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UGIExceptionMessages.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UGIExceptionMessages.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UGIExceptionMessages.java
new file mode 100644
index 0000000..c4d30e5
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UGIExceptionMessages.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.security;
+
+/**
+ * Standard strings to use in exception messages
+ * in {@link KerberosAuthException} when throwing.
+ */
+final class UGIExceptionMessages {
+
+ public static final String FAILURE_TO_LOGIN = "failure to login:";
+ public static final String FOR_USER = " for user: ";
+ public static final String FOR_PRINCIPAL = " for principal: ";
+ public static final String FROM_KEYTAB = " from keytab ";
+ public static final String LOGIN_FAILURE = "Login failure";
+ public static final String LOGOUT_FAILURE = "Logout failure";
+ public static final String MUST_FIRST_LOGIN =
+ "login must be done first";
+ public static final String MUST_FIRST_LOGIN_FROM_KEYTAB =
+ "loginUserFromKeyTab must be done first";
+ public static final String SUBJECT_MUST_CONTAIN_PRINCIPAL =
+ "Provided Subject must contain a KerberosPrincipal";
+ public static final String SUBJECT_MUST_NOT_BE_NULL =
+ "Subject must not be null";
+ public static final String USING_TICKET_CACHE_FILE =
+ " using ticket cache file: ";
+
+ //checkstyle: Utility classes should not have a public or default constructor.
+ private UGIExceptionMessages() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/2e853be6/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java
----------------------------------------------------------------------
diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java
index 637e3fa..329859d 100644
--- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java
@@ -21,6 +21,7 @@ import static org.apache.hadoop.fs.CommonConfigurationKeys.HADOOP_USER_GROUP_MET
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_KERBEROS_MIN_SECONDS_BEFORE_RELOGIN;
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_KERBEROS_MIN_SECONDS_BEFORE_RELOGIN_DEFAULT;
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;
@@ -755,8 +756,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;
}
}
@@ -765,16 +769,17 @@ public class UserGroupInformation {
*
* @param subject 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 =
@@ -894,7 +899,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);
@@ -1001,7 +1006,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
@@ -1030,8 +1036,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);
@@ -1042,8 +1050,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
@@ -1054,7 +1063,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 {
@@ -1065,9 +1074,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
@@ -1078,6 +1088,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()
@@ -1099,12 +1110,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)
@@ -1124,7 +1135,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;
@@ -1156,8 +1167,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;
}
}
@@ -1166,19 +1179,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)) {
@@ -1205,8 +1218,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;
}
}
@@ -1252,8 +1266,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;
---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org