YARN-4126. RM should not issue delegation tokens in unsecure mode. Contributed by Bibin A Chundatt
(cherry picked from commit e1b1d7e4ae
)
This commit is contained in:
parent
1f9f219062
commit
b705d9d0ac
|
@ -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
|
||||
|
||||
|
|
|
@ -1099,7 +1099,7 @@ public class ClientRMService extends AbstractService implements
|
|||
.contains(UserGroupInformation.getCurrentUser()
|
||||
.getRealAuthenticationMethod());
|
||||
} else {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Void>() {
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
checkTokenRenewal(owner, owner);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTokenRenewalWrongUser() throws Exception {
|
||||
try {
|
||||
owner.doAs(new PrivilegedExceptionAction<Void>() {
|
||||
@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<Void>() {
|
||||
@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<RMDelegationTokenIdentifier>(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<Void>() {
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
checkTokenCancellation(rmService, testerKerb, other);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
owner.doAs(new PrivilegedExceptionAction<Void>() {
|
||||
@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<Void>() {
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
checkTokenCancellation(rmService, owner, testerKerb);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
other.doAs(new PrivilegedExceptionAction<Void>() {
|
||||
@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<Void>() {
|
||||
@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<Void>() {
|
||||
@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<RMDelegationTokenIdentifier>(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 {
|
||||
|
|
|
@ -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<Void>() {
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
checkTokenCancellation(rmService, testerKerb, other);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
owner.doAs(new PrivilegedExceptionAction<Void>() {
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
checkTokenCancellation(owner, other);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTokenRenewalWrongUser() throws Exception {
|
||||
try {
|
||||
owner.doAs(new PrivilegedExceptionAction<Void>() {
|
||||
@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<Void>() {
|
||||
@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<RMDelegationTokenIdentifier>(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<Void>() {
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
checkTokenCancellation(rmService, owner, testerKerb);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
other.doAs(new PrivilegedExceptionAction<Void>() {
|
||||
@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<Void>() {
|
||||
@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<Void>() {
|
||||
@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<RMDelegationTokenIdentifier>(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<Void>() {
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
checkTokenRenewal(owner, owner);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue