diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index f1fbb54b38..846aef729d 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -333,6 +333,9 @@ Release 2.0.3-alpha - Unreleased HADOOP-8985. Add namespace declarations in .proto files for languages other than java. (Binglin Chan via suresh) + HADOOP-9009. Add SecurityUtil methods to get/set authentication method + (daryn via bobby) + OPTIMIZATIONS HADOOP-8866. SampleQuantiles#query is O(N^2) instead of O(N). (Andrew Wang diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java index 66ffe20c6b..717c54d713 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java @@ -16,6 +16,8 @@ */ package org.apache.hadoop.security; +import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION; + import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -44,6 +46,7 @@ import org.apache.hadoop.http.HttpConfig; import org.apache.hadoop.io.Text; import org.apache.hadoop.net.NetUtils; +import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; import org.apache.hadoop.security.authentication.client.AuthenticatedURL; import org.apache.hadoop.security.authentication.client.AuthenticationException; import org.apache.hadoop.security.ssl.SSLFactory; @@ -665,4 +668,22 @@ void setSearchDomains(String ... domains) { } } + public static AuthenticationMethod getAuthenticationMethod(Configuration conf) { + String value = conf.get(HADOOP_SECURITY_AUTHENTICATION, "simple"); + try { + return Enum.valueOf(AuthenticationMethod.class, value.toUpperCase()); + } catch (IllegalArgumentException iae) { + throw new IllegalArgumentException("Invalid attribute value for " + + HADOOP_SECURITY_AUTHENTICATION + " of " + value); + } + } + + public static void setAuthenticationMethod( + AuthenticationMethod authenticationMethod, Configuration conf) { + if (authenticationMethod == null) { + authenticationMethod = AuthenticationMethod.SIMPLE; + } + conf.set(HADOOP_SECURITY_AUTHENTICATION, + authenticationMethod.toString().toLowerCase()); + } } 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 7c3f6677b4..4b9545032a 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 @@ -236,15 +236,15 @@ private static synchronized void initialize(Configuration conf, boolean skipRule * @param conf the configuration to use */ private static synchronized void initUGI(Configuration conf) { - String value = conf.get(HADOOP_SECURITY_AUTHENTICATION); - if (value == null || "simple".equals(value)) { + AuthenticationMethod auth = SecurityUtil.getAuthenticationMethod(conf); + if (auth == AuthenticationMethod.SIMPLE) { useKerberos = false; - } else if ("kerberos".equals(value)) { + } else if (auth == AuthenticationMethod.KERBEROS) { useKerberos = true; } else { throw new IllegalArgumentException("Invalid attribute value for " + HADOOP_SECURITY_AUTHENTICATION + - " of " + value); + " of " + auth); } try { kerberosMinSecondsBeforeRelogin = 1000L * conf.getLong( diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/MiniRPCBenchmark.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/MiniRPCBenchmark.java index 5130bad1a6..edf95d7480 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/MiniRPCBenchmark.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/MiniRPCBenchmark.java @@ -30,7 +30,6 @@ import org.apache.commons.logging.impl.Log4JLogger; import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.fs.CommonConfigurationKeys; import org.apache.hadoop.io.Text; import org.apache.hadoop.net.NetUtils; import org.apache.hadoop.security.KerberosInfo; @@ -380,9 +379,7 @@ public static void main(String[] args) throws Exception { elapsedTime = mb.runMiniBenchmarkWithDelegationToken( conf, count, KEYTAB_FILE_KEY, USER_NAME_KEY); } else { - String auth = - conf.get(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, - "simple"); + String auth = SecurityUtil.getAuthenticationMethod(conf).toString(); System.out.println( "Running MiniRPCBenchmark with " + auth + " authentication."); elapsedTime = mb.runMiniBenchmark( diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestRPC.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestRPC.java index 732431d2a1..745eb79284 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestRPC.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestRPC.java @@ -55,13 +55,16 @@ import org.apache.hadoop.metrics2.MetricsRecordBuilder; import org.apache.hadoop.net.NetUtils; import org.apache.hadoop.security.AccessControlException; +import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; import org.apache.hadoop.security.authorize.AuthorizationException; import org.apache.hadoop.security.authorize.PolicyProvider; import org.apache.hadoop.security.authorize.Service; import org.apache.hadoop.security.token.SecretManager; import org.apache.hadoop.security.token.TokenIdentifier; import org.apache.hadoop.test.MockitoUtil; +import org.junit.Before; import org.junit.Test; import com.google.protobuf.DescriptorProtos; @@ -75,11 +78,14 @@ public class TestRPC { public static final Log LOG = LogFactory.getLog(TestRPC.class); - private static Configuration conf = new Configuration(); + private static Configuration conf; - static { + @Before + public void setupConf() { + conf = new Configuration(); conf.setClass("rpc.engine." + StoppedProtocol.class.getName(), StoppedRpcEngine.class, RpcEngine.class); + UserGroupInformation.setConfiguration(conf); } int datasize = 1024*100; @@ -676,11 +682,17 @@ public void testWrappedStopProxy() throws IOException { @Test public void testErrorMsgForInsecureClient() throws Exception { - final Server server = new RPC.Builder(conf).setProtocol(TestProtocol.class) + Configuration serverConf = new Configuration(conf); + SecurityUtil.setAuthenticationMethod(AuthenticationMethod.KERBEROS, + serverConf); + UserGroupInformation.setConfiguration(serverConf); + + final Server server = new RPC.Builder(serverConf).setProtocol(TestProtocol.class) .setInstance(new TestImpl()).setBindAddress(ADDRESS).setPort(0) .setNumHandlers(5).setVerbose(true).build(); - server.enableSecurity(); server.start(); + + UserGroupInformation.setConfiguration(conf); boolean succeeded = false; final InetSocketAddress addr = NetUtils.getConnectAddress(server); TestProtocol proxy = null; @@ -702,17 +714,18 @@ public void testErrorMsgForInsecureClient() throws Exception { conf.setInt(CommonConfigurationKeys.IPC_SERVER_RPC_READ_THREADS_KEY, 2); - final Server multiServer = new RPC.Builder(conf) + UserGroupInformation.setConfiguration(serverConf); + final Server multiServer = new RPC.Builder(serverConf) .setProtocol(TestProtocol.class).setInstance(new TestImpl()) .setBindAddress(ADDRESS).setPort(0).setNumHandlers(5).setVerbose(true) .build(); - multiServer.enableSecurity(); multiServer.start(); succeeded = false; final InetSocketAddress mulitServerAddr = NetUtils.getConnectAddress(multiServer); proxy = null; try { + UserGroupInformation.setConfiguration(conf); proxy = (TestProtocol) RPC.getProxy(TestProtocol.class, TestProtocol.versionID, mulitServerAddr, conf); proxy.echo(""); diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java index f1b5fd67fd..6a4684e788 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestSaslRPC.java @@ -18,8 +18,9 @@ package org.apache.hadoop.ipc; -import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION; +import static org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod.*; import static org.junit.Assert.*; + import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; @@ -78,7 +79,7 @@ public class TestSaslRPC { @BeforeClass public static void setup() { conf = new Configuration(); - conf.set(HADOOP_SECURITY_AUTHENTICATION, "kerberos"); + SecurityUtil.setAuthenticationMethod(KERBEROS, conf); UserGroupInformation.setConfiguration(conf); } @@ -263,7 +264,6 @@ public void testSecureToInsecureRpc() throws Exception { Server server = new RPC.Builder(conf).setProtocol(TestSaslProtocol.class) .setInstance(new TestSaslImpl()).setBindAddress(ADDRESS).setPort(0) .setNumHandlers(5).setVerbose(true).build(); - server.disableSecurity(); TestTokenSecretManager sm = new TestTokenSecretManager(); doDigestRpc(server, sm); } @@ -345,7 +345,7 @@ public void testGetRemotePrincipal() throws Exception { new InetSocketAddress(0), TestSaslProtocol.class, null, 0, newConf); assertEquals(SERVER_PRINCIPAL_1, remoteId.getServerPrincipal()); // this following test needs security to be off - newConf.set(HADOOP_SECURITY_AUTHENTICATION, "simple"); + SecurityUtil.setAuthenticationMethod(SIMPLE, newConf); UserGroupInformation.setConfiguration(newConf); remoteId = ConnectionId.getConnectionId(new InetSocketAddress(0), TestSaslProtocol.class, null, 0, newConf); @@ -536,15 +536,15 @@ private AuthenticationMethod getAuthMethod(final boolean isSecureClient, final boolean useToken ) throws Exception { + Configuration serverConf = new Configuration(conf); + SecurityUtil.setAuthenticationMethod( + isSecureServer ? KERBEROS : SIMPLE, serverConf); + UserGroupInformation.setConfiguration(serverConf); + TestTokenSecretManager sm = new TestTokenSecretManager(); - Server server = new RPC.Builder(conf).setProtocol(TestSaslProtocol.class) + Server server = new RPC.Builder(serverConf).setProtocol(TestSaslProtocol.class) .setInstance(new TestSaslImpl()).setBindAddress(ADDRESS).setPort(0) .setNumHandlers(5).setVerbose(true).setSecretManager(sm).build(); - if (isSecureServer) { - server.enableSecurity(); - } else { - server.disableSecurity(); - } server.start(); final UserGroupInformation current = UserGroupInformation.getCurrentUser(); @@ -558,8 +558,10 @@ private AuthenticationMethod getAuthMethod(final boolean isSecureClient, current.addToken(token); } - conf.set(HADOOP_SECURITY_AUTHENTICATION, isSecureClient ? "kerberos" : "simple"); - UserGroupInformation.setConfiguration(conf); + final Configuration clientConf = new Configuration(conf); + SecurityUtil.setAuthenticationMethod( + isSecureClient ? KERBEROS : SIMPLE, clientConf); + UserGroupInformation.setConfiguration(clientConf); try { return current.doAs(new PrivilegedExceptionAction() { @Override @@ -567,7 +569,7 @@ public AuthenticationMethod run() throws IOException { TestSaslProtocol proxy = null; try { proxy = (TestSaslProtocol) RPC.getProxy(TestSaslProtocol.class, - TestSaslProtocol.versionID, addr, conf); + TestSaslProtocol.versionID, addr, clientConf); return proxy.getAuthMethod(); } finally { if (proxy != null) { diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestDoAsEffectiveUser.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestDoAsEffectiveUser.java index 529124eddf..129d4a06d0 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestDoAsEffectiveUser.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestDoAsEffectiveUser.java @@ -28,13 +28,13 @@ import junit.framework.Assert; import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.fs.CommonConfigurationKeys; import org.apache.hadoop.io.Text; import org.apache.hadoop.ipc.ProtocolSignature; import org.apache.hadoop.ipc.RPC; import org.apache.hadoop.ipc.Server; import org.apache.hadoop.ipc.VersionedProtocol; import org.apache.hadoop.net.NetUtils; +import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; import org.apache.hadoop.security.authorize.ProxyUsers; import org.apache.hadoop.security.token.Token; import org.apache.hadoop.security.token.TokenInfo; @@ -416,8 +416,7 @@ public String run() throws IOException { public void testProxyWithToken() throws Exception { final Configuration conf = new Configuration(masterConf); TestTokenSecretManager sm = new TestTokenSecretManager(); - conf - .set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, "kerberos"); + SecurityUtil.setAuthenticationMethod(AuthenticationMethod.KERBEROS, conf); UserGroupInformation.setConfiguration(conf); final Server server = new RPC.Builder(conf).setProtocol(TestProtocol.class) .setInstance(new TestImpl()).setBindAddress(ADDRESS).setPort(0) @@ -471,8 +470,7 @@ public String run() throws Exception { public void testTokenBySuperUser() throws Exception { TestTokenSecretManager sm = new TestTokenSecretManager(); final Configuration newConf = new Configuration(masterConf); - newConf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, - "kerberos"); + SecurityUtil.setAuthenticationMethod(AuthenticationMethod.KERBEROS, newConf); UserGroupInformation.setConfiguration(newConf); final Server server = new RPC.Builder(newConf) .setProtocol(TestProtocol.class).setInstance(new TestImpl()) diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestSecurityUtil.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestSecurityUtil.java index cc22796ab1..f709639413 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestSecurityUtil.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestSecurityUtil.java @@ -16,6 +16,8 @@ */ package org.apache.hadoop.security; +import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION; +import static org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod.*; import static org.junit.Assert.*; import java.io.IOException; @@ -29,10 +31,19 @@ import org.apache.hadoop.io.Text; import org.apache.hadoop.net.NetUtils; import org.apache.hadoop.security.token.Token; +import org.apache.hadoop.security.token.TokenIdentifier; +import org.junit.BeforeClass; import org.junit.Test; import org.mockito.Mockito; public class TestSecurityUtil { + @BeforeClass + public static void unsetKerberosRealm() { + // prevent failures if kinit-ed or on os x with no realm + System.setProperty("java.security.krb5.kdc", ""); + System.setProperty("java.security.krb5.realm", "NONE"); + } + @Test public void isOriginalTGTReturnsCorrectValues() { assertTrue(SecurityUtil.isTGSPrincipal @@ -111,9 +122,7 @@ public void testLocalHostNameForNullOrWild() throws Exception { @Test public void testStartsWithIncorrectSettings() throws IOException { Configuration conf = new Configuration(); - conf.set( - org.apache.hadoop.fs.CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, - "kerberos"); + SecurityUtil.setAuthenticationMethod(KERBEROS, conf); String keyTabKey="key"; conf.set(keyTabKey, ""); UserGroupInformation.setConfiguration(conf); @@ -256,7 +265,7 @@ void runBadPortPermutes(String arg, boolean validIfPosPort) { SecurityUtil.setTokenServiceUseIp(useIp); String serviceHost = useIp ? ip : host.toLowerCase(); - Token token = new Token(); + Token token = new Token(); Text service = new Text(serviceHost+":"+port); assertEquals(service, SecurityUtil.buildTokenService(addr)); @@ -345,4 +354,43 @@ public void testSocketAddrWithIPToStaticIP() { NetUtils.addStaticResolution(staticHost, "255.255.255.255"); verifyServiceAddr(staticHost, "255.255.255.255"); } + + @Test + public void testGetAuthenticationMethod() { + Configuration conf = new Configuration(); + // default is simple + conf.unset(HADOOP_SECURITY_AUTHENTICATION); + assertEquals(SIMPLE, SecurityUtil.getAuthenticationMethod(conf)); + // simple + conf.set(HADOOP_SECURITY_AUTHENTICATION, "simple"); + assertEquals(SIMPLE, SecurityUtil.getAuthenticationMethod(conf)); + // kerberos + conf.set(HADOOP_SECURITY_AUTHENTICATION, "kerberos"); + assertEquals(KERBEROS, SecurityUtil.getAuthenticationMethod(conf)); + // bad value + conf.set(HADOOP_SECURITY_AUTHENTICATION, "kaboom"); + String error = null; + try { + SecurityUtil.getAuthenticationMethod(conf); + } catch (Exception e) { + error = e.toString(); + } + assertEquals("java.lang.IllegalArgumentException: " + + "Invalid attribute value for " + + HADOOP_SECURITY_AUTHENTICATION + " of kaboom", error); + } + + @Test + public void testSetAuthenticationMethod() { + Configuration conf = new Configuration(); + // default + SecurityUtil.setAuthenticationMethod(null, conf); + assertEquals("simple", conf.get(HADOOP_SECURITY_AUTHENTICATION)); + // simple + SecurityUtil.setAuthenticationMethod(SIMPLE, conf); + assertEquals("simple", conf.get(HADOOP_SECURITY_AUTHENTICATION)); + // kerberos + SecurityUtil.setAuthenticationMethod(KERBEROS, conf); + assertEquals("kerberos", conf.get(HADOOP_SECURITY_AUTHENTICATION)); + } } diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUGIWithSecurityOn.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUGIWithSecurityOn.java index 3dc69783df..a158593351 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUGIWithSecurityOn.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUGIWithSecurityOn.java @@ -21,7 +21,6 @@ import junit.framework.Assert; import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.fs.CommonConfigurationKeys; import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; import org.junit.Assume; import org.junit.Before; @@ -49,8 +48,7 @@ public void testLogin() throws IOException { String user1keyTabFilepath = System.getProperty("kdc.resource.dir") + "/keytabs/user1.keytab"; Configuration conf = new Configuration(); - conf.set(CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION, - "kerberos"); + SecurityUtil.setAuthenticationMethod(AuthenticationMethod.KERBEROS, conf); UserGroupInformation.setConfiguration(conf); UserGroupInformation ugiNn = UserGroupInformation