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 da...@apache.org on 2013/03/18 15:05:10 UTC
svn commit: r1457770 - in
/hadoop/common/branches/branch-2/hadoop-common-project:
hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/
hadoop-common/ hadoop-common/src/main/java/org/apache/hadoop/security/
hadoop-common/src/test/ja...
Author: daryn
Date: Mon Mar 18 14:05:09 2013
New Revision: 1457770
URL: http://svn.apache.org/r1457770
Log:
svn merge -c 1457763 FIXES: HADOOP-9299. kerberos name resolution is kicking in even when kerberos is not configured (daryn)
Modified:
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/KerberosName.java
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/HadoopKerberosName.java
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java
hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java
Modified: hadoop/common/branches/branch-2/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/KerberosName.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/KerberosName.java?rev=1457770&r1=1457769&r2=1457770&view=diff
==============================================================================
--- hadoop/common/branches/branch-2/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/KerberosName.java (original)
+++ hadoop/common/branches/branch-2/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/KerberosName.java Mon Mar 18 14:05:09 2013
@@ -383,10 +383,26 @@ public class KerberosName {
* @param ruleString the rules string.
*/
public static void setRules(String ruleString) {
- rules = parseRules(ruleString);
+ rules = (ruleString != null) ? parseRules(ruleString) : null;
}
/**
+ * Get the rules.
+ * @return String of configured rules, or null if not yet configured
+ */
+ public static String getRules() {
+ String ruleString = null;
+ if (rules != null) {
+ StringBuilder sb = new StringBuilder();
+ for (Rule rule : rules) {
+ sb.append(rule.toString()).append("\n");
+ }
+ ruleString = sb.toString().trim();
+ }
+ return ruleString;
+ }
+
+ /**
* Indicates if the name rules have been set.
*
* @return if the name rules have been set.
Modified: hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt?rev=1457770&r1=1457769&r2=1457770&view=diff
==============================================================================
--- hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt (original)
+++ hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/CHANGES.txt Mon Mar 18 14:05:09 2013
@@ -85,6 +85,9 @@ Release 2.0.5-beta - UNRELEASED
HADOOP-9407. commons-daemon 1.0.3 dependency has bad group id causing
build issues. (Sangjin Lee via suresh)
+ HADOOP-9299. kerberos name resolution is kicking in even when kerberos
+ is not configured (daryn)
+
Release 2.0.4-alpha - UNRELEASED
INCOMPATIBLE CHANGES
Modified: hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/HadoopKerberosName.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/HadoopKerberosName.java?rev=1457770&r1=1457769&r2=1457770&view=diff
==============================================================================
--- hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/HadoopKerberosName.java (original)
+++ hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/HadoopKerberosName.java Mon Mar 18 14:05:09 2013
@@ -18,6 +18,8 @@
package org.apache.hadoop.security;
+import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTH_TO_LOCAL;
+
import java.io.IOException;
import org.apache.hadoop.classification.InterfaceAudience;
@@ -25,7 +27,6 @@ import org.apache.hadoop.classification.
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.authentication.util.KerberosName;
import org.apache.hadoop.security.authentication.util.KerberosUtil;
-import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
/**
* This class implements parsing and handling of Kerberos principal names. In
* particular, it splits them apart and translates them down into local
@@ -36,15 +37,6 @@ import org.apache.hadoop.fs.CommonConfig
@InterfaceStability.Evolving
public class HadoopKerberosName extends KerberosName {
- static {
- try {
- KerberosUtil.getDefaultRealm();
- } catch (Exception ke) {
- if(UserGroupInformation.isSecurityEnabled())
- throw new IllegalArgumentException("Can't get Kerberos configuration",ke);
- }
- }
-
/**
* Create a name from the full Kerberos principal name.
* @param name
@@ -63,7 +55,23 @@ public class HadoopKerberosName extends
* @throws IOException
*/
public static void setConfiguration(Configuration conf) throws IOException {
- String ruleString = conf.get(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTH_TO_LOCAL, "DEFAULT");
+ final String defaultRule;
+ switch (SecurityUtil.getAuthenticationMethod(conf)) {
+ case KERBEROS:
+ case KERBEROS_SSL:
+ try {
+ KerberosUtil.getDefaultRealm();
+ } catch (Exception ke) {
+ throw new IllegalArgumentException("Can't get Kerberos realm", ke);
+ }
+ defaultRule = "DEFAULT";
+ break;
+ default:
+ // just extract the simple user name
+ defaultRule = "RULE:[1:$1] RULE:[2:$1]";
+ break;
+ }
+ String ruleString = conf.get(HADOOP_SECURITY_AUTH_TO_LOCAL, defaultRule);
setRules(ruleString);
}
Modified: hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java?rev=1457770&r1=1457769&r2=1457770&view=diff
==============================================================================
--- hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java (original)
+++ hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java Mon Mar 18 14:05:09 2013
@@ -51,14 +51,12 @@ import org.apache.commons.logging.LogFac
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.metrics2.annotation.Metric;
import org.apache.hadoop.metrics2.annotation.Metrics;
import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
import org.apache.hadoop.metrics2.lib.MutableRate;
import org.apache.hadoop.security.SaslRpcServer.AuthMethod;
-import org.apache.hadoop.security.authentication.util.KerberosName;
import org.apache.hadoop.security.authentication.util.KerberosUtil;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.TokenIdentifier;
@@ -190,8 +188,6 @@ public class UserGroupInformation {
/** Metrics to track UGI activity */
static UgiMetrics metrics = UgiMetrics.create();
- /** Are the static variables that depend on configuration initialized? */
- private static boolean isInitialized = false;
/** The auth method to use */
private static AuthenticationMethod authenticationMethod;
/** Server-side groups fetching service */
@@ -212,8 +208,8 @@ public class UserGroupInformation {
* Must be called before useKerberos or groups is used.
*/
private static synchronized void ensureInitialized() {
- if (!isInitialized) {
- initialize(new Configuration(), KerberosName.hasRulesBeenSet());
+ if (conf == null) {
+ initialize(new Configuration(), false);
}
}
@@ -221,30 +217,21 @@ public class UserGroupInformation {
* Initialize UGI and related classes.
* @param conf the configuration to use
*/
- private static synchronized void initialize(Configuration conf, boolean skipRulesSetting) {
- initUGI(conf);
- // give the configuration on how to translate Kerberos names
- try {
- if (!skipRulesSetting) {
+ private static synchronized void initialize(Configuration conf,
+ boolean overrideNameRules) {
+ authenticationMethod = SecurityUtil.getAuthenticationMethod(conf);
+ if (overrideNameRules || !HadoopKerberosName.hasRulesBeenSet()) {
+ try {
HadoopKerberosName.setConfiguration(conf);
+ } catch (IOException ioe) {
+ throw new RuntimeException(
+ "Problem with Kerberos auth_to_local name configuration", ioe);
}
- } catch (IOException ioe) {
- throw new RuntimeException("Problem with Kerberos auth_to_local name " +
- "configuration", ioe);
}
- }
-
- /**
- * Set the configuration values for UGI.
- * @param conf the configuration to use
- */
- private static synchronized void initUGI(Configuration conf) {
- authenticationMethod = SecurityUtil.getAuthenticationMethod(conf);
// If we haven't set up testing groups, use the configuration to find it
if (!(groups instanceof TestingGroups)) {
groups = Groups.getUserToGroupsMappingService(conf);
}
- isInitialized = true;
UserGroupInformation.conf = conf;
}
@@ -257,7 +244,17 @@ public class UserGroupInformation {
@InterfaceAudience.Public
@InterfaceStability.Evolving
public static void setConfiguration(Configuration conf) {
- initialize(conf, false);
+ initialize(conf, true);
+ }
+
+ @InterfaceAudience.Private
+ @VisibleForTesting
+ static void reset() {
+ authenticationMethod = null;
+ conf = null;
+ groups = null;
+ setLoginUser(null);
+ HadoopKerberosName.setRules(null);
}
/**
Modified: hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java?rev=1457770&r1=1457769&r2=1457770&view=diff
==============================================================================
--- hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java (original)
+++ hadoop/common/branches/branch-2/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java Mon Mar 18 14:05:09 2013
@@ -37,10 +37,12 @@ import org.apache.hadoop.conf.Configurat
import org.apache.hadoop.io.Text;
import org.apache.hadoop.metrics2.MetricsRecordBuilder;
import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
+import org.apache.hadoop.security.authentication.util.KerberosName;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.TokenIdentifier;
import static org.apache.hadoop.test.MetricsAsserts.*;
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
+import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTH_TO_LOCAL;
public class TestUserGroupInformation {
final private static String USER_NAME = "user1@HADOOP.APACHE.ORG";
@@ -71,17 +73,18 @@ public class TestUserGroupInformation {
public static void setup() {
javax.security.auth.login.Configuration.setConfiguration(
new DummyLoginConfiguration());
+ // doesn't matter what it is, but getGroups needs it set...
+ System.setProperty("hadoop.home.dir", "/tmp");
+ // fake the realm is kerberos is enabled
+ System.setProperty("java.security.krb5.kdc", "");
+ System.setProperty("java.security.krb5.realm", "DEFAULT.REALM");
}
@Before
public void setupUgi() {
conf = new Configuration();
- conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTH_TO_LOCAL,
- "RULE:[2:$1@$0](.*@HADOOP.APACHE.ORG)s/@.*//" +
- "RULE:[1:$1@$0](.*@HADOOP.APACHE.ORG)s/@.*//"
- + "DEFAULT");
+ UserGroupInformation.reset();
UserGroupInformation.setConfiguration(conf);
- UserGroupInformation.setLoginUser(null);
}
@After
@@ -209,31 +212,141 @@ public class TestUserGroupInformation {
/** test constructor */
@Test
public void testConstructor() throws Exception {
- UserGroupInformation ugi =
- UserGroupInformation.createUserForTesting("user2/cron@HADOOP.APACHE.ORG",
- GROUP_NAMES);
- // make sure the short and full user names are correct
- assertEquals("user2/cron@HADOOP.APACHE.ORG", ugi.getUserName());
- assertEquals("user2", ugi.getShortUserName());
- ugi = UserGroupInformation.createUserForTesting(USER_NAME, GROUP_NAMES);
- assertEquals("user1", ugi.getShortUserName());
+ // security off, so default should just return simple name
+ testConstructorSuccess("user1", "user1");
+ testConstructorSuccess("user2@DEFAULT.REALM", "user2");
+ testConstructorSuccess("user3/cron@DEFAULT.REALM", "user3");
+ testConstructorSuccess("user4@OTHER.REALM", "user4");
+ testConstructorSuccess("user5/cron@OTHER.REALM", "user5");
+ // failure test
+ testConstructorFailures(null);
+ testConstructorFailures("");
+ }
+
+ /** test constructor */
+ @Test (timeout = 30000)
+ public void testConstructorWithRules() throws Exception {
+ // security off, but use rules if explicitly set
+ conf.set(HADOOP_SECURITY_AUTH_TO_LOCAL,
+ "RULE:[1:$1@$0](.*@OTHER.REALM)s/(.*)@.*/other-$1/");
+ UserGroupInformation.setConfiguration(conf);
+ testConstructorSuccess("user1", "user1");
+ testConstructorSuccess("user4@OTHER.REALM", "other-user4");
+ // failure test
+ testConstructorFailures("user2@DEFAULT.REALM");
+ testConstructorFailures("user3/cron@DEFAULT.REALM");
+ testConstructorFailures("user5/cron@OTHER.REALM");
+ testConstructorFailures(null);
+ testConstructorFailures("");
+ }
+
+ /** test constructor */
+ @Test (timeout = 30000)
+ public void testConstructorWithKerberos() throws Exception {
+ // security on, default is remove default realm
+ SecurityUtil.setAuthenticationMethod(AuthenticationMethod.KERBEROS, conf);
+ UserGroupInformation.setConfiguration(conf);
+
+ testConstructorSuccess("user1", "user1");
+ testConstructorSuccess("user2@DEFAULT.REALM", "user2");
+ testConstructorSuccess("user3/cron@DEFAULT.REALM", "user3");
+ // failure test
+ testConstructorFailures("user4@OTHER.REALM");
+ testConstructorFailures("user5/cron@OTHER.REALM");
+ testConstructorFailures(null);
+ testConstructorFailures("");
+ }
+
+ /** test constructor */
+ @Test (timeout = 30000)
+ public void testConstructorWithKerberosRules() throws Exception {
+ // security on, explicit rules
+ SecurityUtil.setAuthenticationMethod(AuthenticationMethod.KERBEROS, conf);
+ conf.set(HADOOP_SECURITY_AUTH_TO_LOCAL,
+ "RULE:[2:$1@$0](.*@OTHER.REALM)s/(.*)@.*/other-$1/" +
+ "RULE:[1:$1@$0](.*@OTHER.REALM)s/(.*)@.*/other-$1/" +
+ "DEFAULT");
+ UserGroupInformation.setConfiguration(conf);
+ testConstructorSuccess("user1", "user1");
+ testConstructorSuccess("user2@DEFAULT.REALM", "user2");
+ testConstructorSuccess("user3/cron@DEFAULT.REALM", "user3");
+ testConstructorSuccess("user4@OTHER.REALM", "other-user4");
+ testConstructorSuccess("user5/cron@OTHER.REALM", "other-user5");
// failure test
testConstructorFailures(null);
testConstructorFailures("");
}
+ private void testConstructorSuccess(String principal, String shortName) {
+ UserGroupInformation ugi =
+ UserGroupInformation.createUserForTesting(principal, GROUP_NAMES);
+ // make sure the short and full user names are correct
+ assertEquals(principal, ugi.getUserName());
+ assertEquals(shortName, ugi.getShortUserName());
+ }
+
private void testConstructorFailures(String userName) {
- boolean gotException = false;
try {
UserGroupInformation.createRemoteUser(userName);
- } catch (Exception e) {
- gotException = true;
+ fail("user:"+userName+" wasn't invalid");
+ } catch (IllegalArgumentException e) {
+ String expect = (userName == null || userName.isEmpty())
+ ? "Null user" : "Illegal principal name "+userName;
+ assertEquals(expect, e.getMessage());
}
- assertTrue(gotException);
}
@Test
+ public void testSetConfigWithRules() {
+ String[] rules = { "RULE:[1:TEST1]", "RULE:[1:TEST2]", "RULE:[1:TEST3]" };
+
+ // explicitly set a rule
+ UserGroupInformation.reset();
+ assertFalse(KerberosName.hasRulesBeenSet());
+ KerberosName.setRules(rules[0]);
+ assertTrue(KerberosName.hasRulesBeenSet());
+ assertEquals(rules[0], KerberosName.getRules());
+
+ // implicit init should honor rules already being set
+ UserGroupInformation.createUserForTesting("someone", new String[0]);
+ assertEquals(rules[0], KerberosName.getRules());
+
+ // set conf, should override
+ conf.set(HADOOP_SECURITY_AUTH_TO_LOCAL, rules[1]);
+ UserGroupInformation.setConfiguration(conf);
+ assertEquals(rules[1], KerberosName.getRules());
+
+ // set conf, should again override
+ conf.set(HADOOP_SECURITY_AUTH_TO_LOCAL, rules[2]);
+ UserGroupInformation.setConfiguration(conf);
+ assertEquals(rules[2], KerberosName.getRules());
+
+ // implicit init should honor rules already being set
+ UserGroupInformation.createUserForTesting("someone", new String[0]);
+ assertEquals(rules[2], KerberosName.getRules());
+ }
+
+ @Test (timeout = 30000)
+ public void testEnsureInitWithRules() throws IOException {
+ String rules = "RULE:[1:RULE1]";
+
+ // trigger implicit init, rules should init
+ UserGroupInformation.reset();
+ assertFalse(KerberosName.hasRulesBeenSet());
+ UserGroupInformation.createUserForTesting("someone", new String[0]);
+ assertTrue(KerberosName.hasRulesBeenSet());
+
+ // set a rule, trigger implicit init, rule should not change
+ UserGroupInformation.reset();
+ KerberosName.setRules(rules);
+ assertTrue(KerberosName.hasRulesBeenSet());
+ assertEquals(rules, KerberosName.getRules());
+ UserGroupInformation.createUserForTesting("someone", new String[0]);
+ assertEquals(rules, KerberosName.getRules());
+ }
+
+ @Test (timeout = 30000)
public void testEquals() throws Exception {
UserGroupInformation uugi =
UserGroupInformation.createUserForTesting(USER_NAME, GROUP_NAMES);