From b705d9d0acd704f364bb31641169dae38e87c3f0 Mon Sep 17 00:00:00 2001 From: Jian He Date: Mon, 14 Sep 2015 14:09:19 +0800 Subject: [PATCH] YARN-4126. RM should not issue delegation tokens in unsecure mode. Contributed by Bibin A Chundatt (cherry picked from commit e1b1d7e4aebfed0dec4d7df21561ab37f73ef1d7) --- hadoop-yarn-project/CHANGES.txt | 2 + .../resourcemanager/ClientRMService.java | 2 +- .../resourcemanager/TestClientRMService.java | 255 --------------- .../TestTokenClientRMService.java | 300 ++++++++++++++++++ .../security/TestRMDelegationTokens.java | 3 + .../TestRMWebServicesDelegationTokens.java | 6 +- 6 files changed, 311 insertions(+), 257 deletions(-) create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestTokenClientRMService.java diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt index 7ed78a92540..4d0e036314d 100644 --- a/hadoop-yarn-project/CHANGES.txt +++ b/hadoop-yarn-project/CHANGES.txt @@ -851,6 +851,8 @@ Release 2.7.2 - UNRELEASED YARN-3697. FairScheduler: ContinuousSchedulingThread can fail to shutdown. (Zhihai Xu via kasha) + YARN-4126. RM should not issue delegation tokens in unsecure mode. + (Bibin A Chundatt via jianhe) Release 2.7.1 - 2015-07-06 diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java index e1633cccdf8..43d3de7c7c5 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java @@ -1099,7 +1099,7 @@ public class ClientRMService extends AbstractService implements .contains(UserGroupInformation.getCurrentUser() .getRealAuthenticationMethod()); } else { - return true; + return false; } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java index 6a0b99c7461..0be8bc26358 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java @@ -30,7 +30,6 @@ import static org.mockito.Mockito.when; import java.io.IOException; import java.net.InetSocketAddress; -import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -47,14 +46,10 @@ import java.util.concurrent.CyclicBarrier; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.io.Text; import org.apache.hadoop.security.UserGroupInformation; -import org.apache.hadoop.security.authentication.util.KerberosName; -import org.apache.hadoop.security.token.Token; import org.apache.hadoop.yarn.MockApps; import org.apache.hadoop.yarn.api.ApplicationClientProtocol; import org.apache.hadoop.yarn.api.protocolrecords.ApplicationsRequestScope; -import org.apache.hadoop.yarn.api.protocolrecords.CancelDelegationTokenRequest; import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationAttemptReportRequest; import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationAttemptReportResponse; import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationAttemptsRequest; @@ -79,7 +74,6 @@ import org.apache.hadoop.yarn.api.protocolrecords.GetQueueInfoResponse; import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationRequest; import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationResponse; import org.apache.hadoop.yarn.api.protocolrecords.MoveApplicationAcrossQueuesRequest; -import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionRequest; @@ -123,11 +117,9 @@ import org.apache.hadoop.yarn.exceptions.YarnException; import org.apache.hadoop.yarn.factories.RecordFactory; import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; import org.apache.hadoop.yarn.ipc.YarnRPC; -import org.apache.hadoop.yarn.security.client.RMDelegationTokenIdentifier; import org.apache.hadoop.yarn.server.resourcemanager.ahs.RMApplicationHistoryWriter; import org.apache.hadoop.yarn.server.resourcemanager.metrics.SystemMetricsPublisher; import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager; -import org.apache.hadoop.yarn.server.resourcemanager.recovery.NullRMStateStore; import org.apache.hadoop.yarn.server.resourcemanager.recovery.RMStateStore; import org.apache.hadoop.yarn.server.resourcemanager.reservation.ReservationSystemTestUtil; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp; @@ -144,17 +136,13 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.YarnScheduler; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration; import org.apache.hadoop.yarn.server.resourcemanager.security.QueueACLsManager; -import org.apache.hadoop.yarn.server.resourcemanager.security.RMDelegationTokenSecretManager; import org.apache.hadoop.yarn.server.security.ApplicationACLsManager; import org.apache.hadoop.yarn.server.utils.BuilderUtils; import org.apache.hadoop.yarn.util.Clock; -import org.apache.hadoop.yarn.util.Records; import org.apache.hadoop.yarn.util.UTCClock; import org.apache.hadoop.yarn.util.resource.ResourceCalculator; import org.apache.hadoop.yarn.util.resource.Resources; -import org.junit.AfterClass; import org.junit.Assert; -import org.junit.BeforeClass; import org.junit.Test; import com.google.common.collect.ImmutableSet; @@ -168,31 +156,10 @@ public class TestClientRMService { .getRecordFactory(null); private String appType = "MockApp"; - - private static RMDelegationTokenSecretManager dtsm; private final static String QUEUE_1 = "Q-1"; private final static String QUEUE_2 = "Q-2"; - private final static String kerberosRule = "RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\nDEFAULT"; - static { - KerberosName.setRules(kerberosRule); - } - - @BeforeClass - public static void setupSecretManager() throws IOException { - RMContext rmContext = mock(RMContext.class); - when(rmContext.getStateStore()).thenReturn(new NullRMStateStore()); - dtsm = new RMDelegationTokenSecretManager(60000, 60000, 60000, 60000, rmContext); - dtsm.startThreads(); - } - @AfterClass - public static void teardownSecretManager() { - if (dtsm != null) { - dtsm.stopThreads(); - } - } - @Test public void testGetClusterNodes() throws Exception { MockRM rm = new MockRM() { @@ -617,229 +584,7 @@ public class TestClientRMService { Assert.assertEquals(0, applications1.size()); } - private static final UserGroupInformation owner = - UserGroupInformation.createRemoteUser("owner"); - private static final UserGroupInformation other = - UserGroupInformation.createRemoteUser("other"); - private static final UserGroupInformation tester = - UserGroupInformation.createRemoteUser("tester"); - private static final String testerPrincipal = "tester@EXAMPLE.COM"; - private static final String ownerPrincipal = "owner@EXAMPLE.COM"; - private static final String otherPrincipal = "other@EXAMPLE.COM"; - private static final UserGroupInformation testerKerb = - UserGroupInformation.createRemoteUser(testerPrincipal); - private static final UserGroupInformation ownerKerb = - UserGroupInformation.createRemoteUser(ownerPrincipal); - private static final UserGroupInformation otherKerb = - UserGroupInformation.createRemoteUser(otherPrincipal); - @Test - public void testTokenRenewalByOwner() throws Exception { - owner.doAs(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - checkTokenRenewal(owner, owner); - return null; - } - }); - } - - @Test - public void testTokenRenewalWrongUser() throws Exception { - try { - owner.doAs(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - try { - checkTokenRenewal(owner, other); - return null; - } catch (YarnException ex) { - Assert.assertTrue(ex.getMessage().contains(owner.getUserName() + - " tries to renew a token with renewer " + - other.getUserName())); - throw ex; - } - } - }); - } catch (Exception e) { - return; - } - Assert.fail("renew should have failed"); - } - - @Test - public void testTokenRenewalByLoginUser() throws Exception { - UserGroupInformation.getLoginUser().doAs(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - checkTokenRenewal(owner, owner); - checkTokenRenewal(owner, other); - return null; - } - }); - } - - private void checkTokenRenewal(UserGroupInformation owner, - UserGroupInformation renewer) throws IOException, YarnException { - RMDelegationTokenIdentifier tokenIdentifier = - new RMDelegationTokenIdentifier( - new Text(owner.getUserName()), new Text(renewer.getUserName()), null); - Token token = - new Token(tokenIdentifier, dtsm); - org.apache.hadoop.yarn.api.records.Token dToken = BuilderUtils.newDelegationToken( - token.getIdentifier(), token.getKind().toString(), - token.getPassword(), token.getService().toString()); - RenewDelegationTokenRequest request = - Records.newRecord(RenewDelegationTokenRequest.class); - request.setDelegationToken(dToken); - - RMContext rmContext = mock(RMContext.class); - ClientRMService rmService = new ClientRMService( - rmContext, null, null, null, null, dtsm); - rmService.renewDelegationToken(request); - } - - @Test - public void testTokenCancellationByOwner() throws Exception { - // two tests required - one with a kerberos name - // and with a short name - RMContext rmContext = mock(RMContext.class); - final ClientRMService rmService = - new ClientRMService(rmContext, null, null, null, null, dtsm); - testerKerb.doAs(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - checkTokenCancellation(rmService, testerKerb, other); - return null; - } - }); - owner.doAs(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - checkTokenCancellation(owner, other); - return null; - } - }); - } - - @Test - public void testTokenCancellationByRenewer() throws Exception { - // two tests required - one with a kerberos name - // and with a short name - RMContext rmContext = mock(RMContext.class); - final ClientRMService rmService = - new ClientRMService(rmContext, null, null, null, null, dtsm); - testerKerb.doAs(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - checkTokenCancellation(rmService, owner, testerKerb); - return null; - } - }); - other.doAs(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - checkTokenCancellation(owner, other); - return null; - } - }); - } - - @Test - public void testTokenCancellationByWrongUser() { - // two sets to test - - // 1. try to cancel tokens of short and kerberos users as a kerberos UGI - // 2. try to cancel tokens of short and kerberos users as a simple auth UGI - - RMContext rmContext = mock(RMContext.class); - final ClientRMService rmService = - new ClientRMService(rmContext, null, null, null, null, dtsm); - UserGroupInformation[] kerbTestOwners = - { owner, other, tester, ownerKerb, otherKerb }; - UserGroupInformation[] kerbTestRenewers = - { owner, other, ownerKerb, otherKerb }; - for (final UserGroupInformation tokOwner : kerbTestOwners) { - for (final UserGroupInformation tokRenewer : kerbTestRenewers) { - try { - testerKerb.doAs(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - try { - checkTokenCancellation(rmService, tokOwner, tokRenewer); - Assert.fail("We should not reach here; token owner = " - + tokOwner.getUserName() + ", renewer = " - + tokRenewer.getUserName()); - return null; - } catch (YarnException e) { - Assert.assertTrue(e.getMessage().contains( - testerKerb.getUserName() - + " is not authorized to cancel the token")); - return null; - } - } - }); - } catch (Exception e) { - Assert.fail("Unexpected exception; " + e.getMessage()); - } - } - } - - UserGroupInformation[] simpleTestOwners = - { owner, other, ownerKerb, otherKerb, testerKerb }; - UserGroupInformation[] simpleTestRenewers = - { owner, other, ownerKerb, otherKerb }; - for (final UserGroupInformation tokOwner : simpleTestOwners) { - for (final UserGroupInformation tokRenewer : simpleTestRenewers) { - try { - tester.doAs(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - try { - checkTokenCancellation(tokOwner, tokRenewer); - Assert.fail("We should not reach here; token owner = " - + tokOwner.getUserName() + ", renewer = " - + tokRenewer.getUserName()); - return null; - } catch (YarnException ex) { - Assert.assertTrue(ex.getMessage().contains( - tester.getUserName() - + " is not authorized to cancel the token")); - return null; - } - } - }); - } catch (Exception e) { - Assert.fail("Unexpected exception; " + e.getMessage()); - } - } - } - } - - private void checkTokenCancellation(UserGroupInformation owner, - UserGroupInformation renewer) throws IOException, YarnException { - RMContext rmContext = mock(RMContext.class); - final ClientRMService rmService = - new ClientRMService(rmContext, null, null, null, null, dtsm); - checkTokenCancellation(rmService, owner, renewer); - } - - private void checkTokenCancellation(ClientRMService rmService, - UserGroupInformation owner, UserGroupInformation renewer) - throws IOException, YarnException { - RMDelegationTokenIdentifier tokenIdentifier = - new RMDelegationTokenIdentifier(new Text(owner.getUserName()), - new Text(renewer.getUserName()), null); - Token token = - new Token(tokenIdentifier, dtsm); - org.apache.hadoop.yarn.api.records.Token dToken = - BuilderUtils.newDelegationToken(token.getIdentifier(), token.getKind() - .toString(), token.getPassword(), token.getService().toString()); - CancelDelegationTokenRequest request = - Records.newRecord(CancelDelegationTokenRequest.class); - request.setDelegationToken(dToken); - rmService.cancelDelegationToken(request); - } - @Test (timeout = 30000) @SuppressWarnings ("rawtypes") public void testAppSubmit() throws Exception { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestTokenClientRMService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestTokenClientRMService.java new file mode 100644 index 00000000000..351f068c2bb --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestTokenClientRMService.java @@ -0,0 +1,300 @@ +/** + * 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.yarn.server.resourcemanager; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.security.PrivilegedExceptionAction; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.security.SaslRpcServer.AuthMethod; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authentication.util.KerberosName; +import org.apache.hadoop.security.token.Token; +import org.apache.hadoop.yarn.api.protocolrecords.CancelDelegationTokenRequest; +import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenRequest; +import org.apache.hadoop.yarn.exceptions.YarnException; +import org.apache.hadoop.yarn.security.client.RMDelegationTokenIdentifier; +import org.apache.hadoop.yarn.server.resourcemanager.recovery.NullRMStateStore; +import org.apache.hadoop.yarn.server.resourcemanager.security.RMDelegationTokenSecretManager; +import org.apache.hadoop.yarn.server.utils.BuilderUtils; +import org.apache.hadoop.yarn.util.Records; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class TestTokenClientRMService { + + private final static String kerberosRule = + "RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\nDEFAULT"; + private static RMDelegationTokenSecretManager dtsm; + static { + KerberosName.setRules(kerberosRule); + } + + private static final UserGroupInformation owner = UserGroupInformation + .createRemoteUser("owner", AuthMethod.KERBEROS); + private static final UserGroupInformation other = UserGroupInformation + .createRemoteUser("other", AuthMethod.KERBEROS); + private static final UserGroupInformation tester = UserGroupInformation + .createRemoteUser("tester", AuthMethod.KERBEROS); + private static final String testerPrincipal = "tester@EXAMPLE.COM"; + private static final String ownerPrincipal = "owner@EXAMPLE.COM"; + private static final String otherPrincipal = "other@EXAMPLE.COM"; + private static final UserGroupInformation testerKerb = UserGroupInformation + .createRemoteUser(testerPrincipal, AuthMethod.KERBEROS); + private static final UserGroupInformation ownerKerb = UserGroupInformation + .createRemoteUser(ownerPrincipal, AuthMethod.KERBEROS); + private static final UserGroupInformation otherKerb = UserGroupInformation + .createRemoteUser(otherPrincipal, AuthMethod.KERBEROS); + + @BeforeClass + public static void setupSecretManager() throws IOException { + RMContext rmContext = mock(RMContext.class); + when(rmContext.getStateStore()).thenReturn(new NullRMStateStore()); + dtsm = + new RMDelegationTokenSecretManager(60000, 60000, 60000, 60000, + rmContext); + dtsm.startThreads(); + Configuration conf = new Configuration(); + conf.set("hadoop.security.authentication", "kerberos"); + conf.set("hadoop.security.auth_to_local", kerberosRule); + UserGroupInformation.setConfiguration(conf); + } + + @AfterClass + public static void teardownSecretManager() { + if (dtsm != null) { + dtsm.stopThreads(); + } + } + + @Test + public void testTokenCancellationByOwner() throws Exception { + // two tests required - one with a kerberos name + // and with a short name + RMContext rmContext = mock(RMContext.class); + final ClientRMService rmService = + new ClientRMService(rmContext, null, null, null, null, dtsm); + testerKerb.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + checkTokenCancellation(rmService, testerKerb, other); + return null; + } + }); + owner.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + checkTokenCancellation(owner, other); + return null; + } + }); + } + + @Test + public void testTokenRenewalWrongUser() throws Exception { + try { + owner.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + try { + checkTokenRenewal(owner, other); + return null; + } catch (YarnException ex) { + Assert.assertTrue(ex.getMessage().contains( + owner.getUserName() + " tries to renew a token with renewer " + + other.getUserName())); + throw ex; + } + } + }); + } catch (Exception e) { + return; + } + Assert.fail("renew should have failed"); + } + + @Test + public void testTokenRenewalByLoginUser() throws Exception { + UserGroupInformation.getLoginUser().doAs( + new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + checkTokenRenewal(owner, owner); + checkTokenRenewal(owner, other); + return null; + } + }); + } + + private void checkTokenRenewal(UserGroupInformation owner, + UserGroupInformation renewer) throws IOException, YarnException { + RMDelegationTokenIdentifier tokenIdentifier = + new RMDelegationTokenIdentifier(new Text(owner.getUserName()), + new Text(renewer.getUserName()), null); + Token token = + new Token(tokenIdentifier, dtsm); + org.apache.hadoop.yarn.api.records.Token dToken = + BuilderUtils.newDelegationToken(token.getIdentifier(), token.getKind() + .toString(), token.getPassword(), token.getService().toString()); + RenewDelegationTokenRequest request = + Records.newRecord(RenewDelegationTokenRequest.class); + request.setDelegationToken(dToken); + + RMContext rmContext = mock(RMContext.class); + ClientRMService rmService = + new ClientRMService(rmContext, null, null, null, null, dtsm); + rmService.renewDelegationToken(request); + } + + @Test + public void testTokenCancellationByRenewer() throws Exception { + // two tests required - one with a kerberos name + // and with a short name + RMContext rmContext = mock(RMContext.class); + final ClientRMService rmService = + new ClientRMService(rmContext, null, null, null, null, dtsm); + testerKerb.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + checkTokenCancellation(rmService, owner, testerKerb); + return null; + } + }); + other.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + checkTokenCancellation(owner, other); + return null; + } + }); + } + + @Test + public void testTokenCancellationByWrongUser() { + // two sets to test - + // 1. try to cancel tokens of short and kerberos users as a kerberos UGI + // 2. try to cancel tokens of short and kerberos users as a simple auth UGI + + RMContext rmContext = mock(RMContext.class); + final ClientRMService rmService = + new ClientRMService(rmContext, null, null, null, null, dtsm); + UserGroupInformation[] kerbTestOwners = + { owner, other, tester, ownerKerb, otherKerb }; + UserGroupInformation[] kerbTestRenewers = + { owner, other, ownerKerb, otherKerb }; + for (final UserGroupInformation tokOwner : kerbTestOwners) { + for (final UserGroupInformation tokRenewer : kerbTestRenewers) { + try { + testerKerb.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + try { + checkTokenCancellation(rmService, tokOwner, tokRenewer); + Assert.fail("We should not reach here; token owner = " + + tokOwner.getUserName() + ", renewer = " + + tokRenewer.getUserName()); + return null; + } catch (YarnException e) { + Assert.assertTrue(e.getMessage().contains( + testerKerb.getUserName() + + " is not authorized to cancel the token")); + return null; + } + } + }); + } catch (Exception e) { + Assert.fail("Unexpected exception; " + e.getMessage()); + } + } + } + + UserGroupInformation[] simpleTestOwners = + { owner, other, ownerKerb, otherKerb, testerKerb }; + UserGroupInformation[] simpleTestRenewers = + { owner, other, ownerKerb, otherKerb }; + for (final UserGroupInformation tokOwner : simpleTestOwners) { + for (final UserGroupInformation tokRenewer : simpleTestRenewers) { + try { + tester.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + try { + checkTokenCancellation(tokOwner, tokRenewer); + Assert.fail("We should not reach here; token owner = " + + tokOwner.getUserName() + ", renewer = " + + tokRenewer.getUserName()); + return null; + } catch (YarnException ex) { + Assert.assertTrue(ex.getMessage().contains( + tester.getUserName() + + " is not authorized to cancel the token")); + return null; + } + } + }); + } catch (Exception e) { + Assert.fail("Unexpected exception; " + e.getMessage()); + } + } + } + } + + private void checkTokenCancellation(UserGroupInformation owner, + UserGroupInformation renewer) throws IOException, YarnException { + RMContext rmContext = mock(RMContext.class); + final ClientRMService rmService = + new ClientRMService(rmContext, null, null, null, null, dtsm); + checkTokenCancellation(rmService, owner, renewer); + } + + private void checkTokenCancellation(ClientRMService rmService, + UserGroupInformation owner, UserGroupInformation renewer) + throws IOException, YarnException { + RMDelegationTokenIdentifier tokenIdentifier = + new RMDelegationTokenIdentifier(new Text(owner.getUserName()), + new Text(renewer.getUserName()), null); + Token token = + new Token(tokenIdentifier, dtsm); + org.apache.hadoop.yarn.api.records.Token dToken = + BuilderUtils.newDelegationToken(token.getIdentifier(), token.getKind() + .toString(), token.getPassword(), token.getService().toString()); + CancelDelegationTokenRequest request = + Records.newRecord(CancelDelegationTokenRequest.class); + request.setDelegationToken(dToken); + rmService.cancelDelegationToken(request); + } + + @Test + public void testTokenRenewalByOwner() throws Exception { + owner.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + checkTokenRenewal(owner, owner); + return null; + } + }); + } + +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/security/TestRMDelegationTokens.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/security/TestRMDelegationTokens.java index 2847a89ffff..068d008f34d 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/security/TestRMDelegationTokens.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/security/TestRMDelegationTokens.java @@ -70,6 +70,9 @@ public class TestRMDelegationTokens { // Test the DT mast key in the state-store when the mast key is being rolled. @Test(timeout = 15000) public void testRMDTMasterKeyStateOnRollingMasterKey() throws Exception { + Configuration conf = new Configuration(); + conf.set("hadoop.security.authentication", "kerberos"); + UserGroupInformation.setConfiguration(conf); MemoryRMStateStore memStore = new MemoryRMStateStore(); memStore.init(conf); RMState rmState = memStore.getState(); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesDelegationTokens.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesDelegationTokens.java index dab83433a45..a6d77443323 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesDelegationTokens.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesDelegationTokens.java @@ -38,6 +38,7 @@ import javax.xml.parsers.ParserConfigurationException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.CommonConfigurationKeysPublic; import org.apache.hadoop.minikdc.MiniKdc; +import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.authentication.KerberosTestUtils; import org.apache.hadoop.security.authentication.server.AuthenticationFilter; import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler; @@ -84,7 +85,6 @@ import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.ClientResponse.Status; import com.sun.jersey.api.client.filter.LoggingFilter; import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; -import com.sun.jersey.test.framework.JerseyTest; import com.sun.jersey.test.framework.WebAppDescriptor; @RunWith(Parameterized.class) @@ -246,6 +246,9 @@ public class TestRMWebServicesDelegationTokens extends JerseyTestBase { super.setUp(); httpSpnegoKeytabFile.deleteOnExit(); testRootDir.deleteOnExit(); + Configuration conf = new Configuration(); + conf.set("hadoop.security.authentication", "kerberos"); + UserGroupInformation.setConfiguration(conf); } @AfterClass @@ -260,6 +263,7 @@ public class TestRMWebServicesDelegationTokens extends JerseyTestBase { public void tearDown() throws Exception { rm.stop(); super.tearDown(); + UserGroupInformation.setConfiguration(new Configuration()); } // Simple test - try to create a delegation token via web services and check