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 om...@apache.org on 2011/03/04 05:13:27 UTC
svn commit: r1077423 [2/2] - in
/hadoop/common/branches/branch-0.20-security-patches: conf/
src/docs/src/documentation/content/xdocs/ src/mapred/
src/mapred/org/apache/hadoop/mapred/ src/test/org/apache/hadoop/mapred/
Modified: hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestQueueManager.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestQueueManager.java?rev=1077423&r1=1077422&r2=1077423&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestQueueManager.java (original)
+++ hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestQueueManager.java Fri Mar 4 04:13:26 2011
@@ -38,12 +38,16 @@ import org.apache.hadoop.examples.SleepJ
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.apache.hadoop.mapred.QueueManager.QueueOperation;
import org.apache.hadoop.security.UserGroupInformation;
public class TestQueueManager extends TestCase {
private static final Log LOG = LogFactory.getLog(TestQueueManager.class);
-
+
+ String submitAcl = QueueOperation.SUBMIT_JOB.getAclName();
+ String adminAcl = QueueOperation.ADMINISTER_JOBS.getAclName();
+
private MiniDFSCluster miniDFSCluster;
private MiniMRCluster miniMRCluster;
@@ -56,13 +60,12 @@ public class TestQueueManager extends Te
private UserGroupInformation createNecessaryUsers() throws IOException {
// Add real user to fake groups mapping so that child processes (tasks)
// will have permissions on the dfs
- String j = UserGroupInformation.getCurrentUser().getUserName();
- UserGroupInformation.createUserForTesting(j, new String [] { "supergroup"});
+ String j = UserGroupInformation.getCurrentUser().getShortUserName();
+ UserGroupInformation.createUserForTesting(j, new String [] { "myGroup"});
-
- // Create a fake superuser for all processes to execute within
+ // Create a fake user for all processes to execute within
UserGroupInformation ugi = UserGroupInformation.createUserForTesting("Zork",
- new String [] {"Zork"});
+ new String [] {"ZorkGroup"});
return ugi;
}
@@ -73,7 +76,7 @@ public class TestQueueManager extends Te
expQueues.add("default");
verifyQueues(expQueues, qMgr.getQueues());
// pass true so it will fail if the key is not found.
- assertFalse(conf.getBoolean("mapred.acls.enabled", true));
+ assertFalse(conf.getBoolean(JobConf.MR_ACLS_ENABLED, true));
}
public void testMultipleQueues() {
@@ -86,7 +89,7 @@ public class TestQueueManager extends Te
expQueues.add("Q3");
verifyQueues(expQueues, qMgr.getQueues());
}
-
+
public void testSchedulerInfo() {
JobConf conf = new JobConf();
conf.set("mapred.queue.names", "qq1,qq2");
@@ -99,35 +102,56 @@ public class TestQueueManager extends Te
public void testAllEnabledACLForJobSubmission()
throws IOException, InterruptedException {
- JobConf conf = setupConf("mapred.queue.default.acl-submit-job", "*");
- verifyJobSubmission(conf, true);
+ JobConf conf = setupConf(QueueManager.toFullPropertyName(
+ "default", submitAcl), "*");
+ UserGroupInformation ugi = createNecessaryUsers();
+ String[] groups = ugi.getGroupNames();
+ verifyJobSubmissionToDefaultQueue(conf, true,
+ ugi.getShortUserName() + "," + groups[groups.length-1]);
}
public void testAllDisabledACLForJobSubmission()
throws IOException, InterruptedException {
- JobConf conf = setupConf("mapred.queue.default.acl-submit-job", "");
- verifyJobSubmission(conf, false);
+ createNecessaryUsers();
+ JobConf conf = setupConf(QueueManager.toFullPropertyName(
+ "default", submitAcl), " ");
+ String userName = "user1";
+ String groupName = "group1";
+ verifyJobSubmissionToDefaultQueue(conf, false, userName + "," + groupName);
+
+ // Check if member of supergroup can submit job
+ conf.set(JobConf.MR_SUPERGROUP, groupName);
+ verifyJobSubmissionToDefaultQueue(conf, true, userName + "," + groupName);
+
+ // Check if MROwner(user who started the mapreduce cluster) can submit job
+ UserGroupInformation mrOwner = UserGroupInformation.getCurrentUser();
+ userName = mrOwner.getShortUserName();
+ String[] groups = mrOwner.getGroupNames();
+ groupName = groups[groups.length - 1];
+ verifyJobSubmissionToDefaultQueue(conf, true, userName + "," + groupName);
}
public void testUserDisabledACLForJobSubmission()
throws IOException, InterruptedException {
- JobConf conf = setupConf("mapred.queue.default.acl-submit-job",
- "3698-non-existent-user");
- verifyJobSubmission(conf, false);
+ JobConf conf = setupConf(QueueManager.toFullPropertyName(
+ "default", submitAcl), "3698-non-existent-user");
+ verifyJobSubmissionToDefaultQueue(conf, false, "user1,group1");
}
public void testDisabledACLForNonDefaultQueue()
throws IOException, InterruptedException {
// allow everyone in default queue
- JobConf conf = setupConf("mapred.queue.default.acl-submit-job", "*");
+ JobConf conf = setupConf(QueueManager.toFullPropertyName(
+ "default", submitAcl), "*");
// setup a different queue
conf.set("mapred.queue.names", "default,q1");
// setup a different acl for this queue.
- conf.set("mapred.queue.q1.acl-submit-job", "dummy-user");
+ conf.set(QueueManager.toFullPropertyName(
+ "q1", submitAcl), "dummy-user");
// verify job submission to other queue fails.
- verifyJobSubmission(conf, false, "q1");
+ verifyJobSubmission(conf, false, "user1,group1", "q1");
}
-
+
public void testSubmissionToInvalidQueue()
throws IOException, InterruptedException{
JobConf conf = new JobConf();
@@ -144,65 +168,62 @@ public class TestQueueManager extends Te
}
fail("Job submission to invalid queue job shouldnot complete , it should fail with proper exception ");
}
-
+
public void testEnabledACLForNonDefaultQueue()
throws IOException, LoginException, InterruptedException {
- // login as self...
- UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
- String userName = ugi.getUserName();
+ UserGroupInformation ugi = createNecessaryUsers();
+ String[] groups = ugi.getGroupNames();
+ String userName = ugi.getShortUserName();
// allow everyone in default queue
- JobConf conf = setupConf("mapred.queue.default.acl-submit-job", "*");
+ JobConf conf = setupConf(QueueManager.toFullPropertyName(
+ "default", submitAcl), "*");
// setup a different queue
conf.set("mapred.queue.names", "default,q2");
// setup a different acl for this queue.
- conf.set("mapred.queue.q2.acl-submit-job", userName);
+ conf.set(QueueManager.toFullPropertyName(
+ "q2", submitAcl), userName);
// verify job submission to other queue fails.
- verifyJobSubmission(conf, true, "q2");
+ verifyJobSubmission(conf, true,
+ userName + "," + groups[groups.length-1], "q2");
}
-
+
public void testUserEnabledACLForJobSubmission()
throws IOException, LoginException, InterruptedException {
- // login as self...
- UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
- String userName = ugi.getUserName();
- JobConf conf = setupConf("mapred.queue.default.acl-submit-job",
- "3698-junk-user," + userName
+ String userName = "user1";
+ JobConf conf = setupConf(QueueManager.toFullPropertyName(
+ "default", submitAcl), "3698-junk-user," + userName
+ " 3698-junk-group1,3698-junk-group2");
- verifyJobSubmission(conf, true);
+ verifyJobSubmissionToDefaultQueue(conf, true, userName+",group1");
}
-
+
public void testGroupsEnabledACLForJobSubmission()
throws IOException, LoginException, InterruptedException {
// login as self, get one group, and add in allowed list.
UserGroupInformation ugi = createNecessaryUsers();
-
- ugi.doAs(new PrivilegedExceptionAction<Object>() {
-
- @Override
- public Object run() throws Exception {
- String[] groups = UserGroupInformation.getCurrentUser().getGroupNames();
- JobConf conf = setupConf("mapred.queue.default.acl-submit-job",
- "3698-junk-user1,3698-junk-user2 "
- + groups[groups.length-1]
- + ",3698-junk-group");
- verifyJobSubmission(conf, true);
-
- return null;
- }
- });
+ String[] groups = ugi.getGroupNames();
+ JobConf conf = setupConf(QueueManager.toFullPropertyName(
+ "default", submitAcl), "3698-junk-user1,3698-junk-user2 "
+ + groups[groups.length-1]
+ + ",3698-junk-group");
+ verifyJobSubmissionToDefaultQueue(conf, true,
+ ugi.getShortUserName()+","+groups[groups.length-1]);
}
-
+
public void testAllEnabledACLForJobKill()
throws IOException, InterruptedException {
UserGroupInformation ugi = createNecessaryUsers();
-
+ // create other user who will try to kill the job of ugi.
+ final UserGroupInformation otherUGI = UserGroupInformation.
+ createUserForTesting("user1", new String [] {"group1"});
+
ugi.doAs(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
- JobConf conf = setupConf("mapred.queue.default.acl-administer-jobs", "*");
- verifyJobKill(conf, true);
+ JobConf conf = setupConf(QueueManager.toFullPropertyName(
+ "default", adminAcl), "*");
+ verifyJobKill(otherUGI, conf, true);
return null;
}
});
@@ -211,16 +232,30 @@ public class TestQueueManager extends Te
public void testAllDisabledACLForJobKill()
throws IOException, InterruptedException {
// Create a fake superuser for all processes to execute within
- UserGroupInformation ugi = createNecessaryUsers();
+ final UserGroupInformation ugi = createNecessaryUsers();
+
+ // create other user who will try to kill the job of ugi.
+ final UserGroupInformation otherUGI = UserGroupInformation.
+ createUserForTesting("user1", new String [] {"group1"});
+
ugi.doAs(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
- // No one should be able to kill jobs
- JobConf conf = setupConf("mapred.queue.default.acl-administer-jobs", "");
- // Run as dummy-user, who (obviously) is not able to kill the job,
- // and expect him to fail
- verifyJobKillAsOtherUser(conf, false, "dummy-user,dummy-group");
+ // No queue admins
+ JobConf conf = setupConf(QueueManager.toFullPropertyName(
+ "default", adminAcl), " ");
+ // Run job as ugi and try to kill job as user1, who (obviously)
+ // should not be able to kill the job.
+ verifyJobKill(otherUGI, conf, false);
+
+ // Check if member of supergroup can kill job
+ conf.set(JobConf.MR_SUPERGROUP, "group1");
+ verifyJobKill(otherUGI, conf, true);
+
+ // Check if MROwner(user who started the mapreduce cluster) can kill job
+ verifyJobKill(ugi, conf, true);
+
return null;
}
});
@@ -228,16 +263,16 @@ public class TestQueueManager extends Te
public void testOwnerAllowedForJobKill()
throws IOException, InterruptedException {
- UserGroupInformation ugi = createNecessaryUsers();
+ final UserGroupInformation ugi = createNecessaryUsers();
ugi.doAs(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
- JobConf conf = setupConf("mapred.queue.default.acl-administer-jobs",
- "junk-user");
- verifyJobKill(conf, true);
+ JobConf conf = setupConf(QueueManager.toFullPropertyName(
+ "default", adminAcl), "junk-user");
+ verifyJobKill(ugi, conf, true);
return null;
}
});
@@ -246,32 +281,41 @@ public class TestQueueManager extends Te
public void testUserDisabledACLForJobKill()
throws IOException, InterruptedException {
UserGroupInformation ugi = createNecessaryUsers();
-
+ // create other user who will try to kill the job of ugi.
+ final UserGroupInformation otherUGI = UserGroupInformation.
+ createUserForTesting("user1", new String [] {"group1"});
+
ugi.doAs(new PrivilegedExceptionAction<Object>() {
+
@Override
public Object run() throws Exception {
- //setup a cluster allowing a user to submit
- JobConf conf = setupConf("mapred.queue.default.acl-administer-jobs",
- "dummy-user");
- verifyJobKillAsOtherUser(conf, false, "dummy-user,dummy-group");
+ //setup a cluster allowing a user to submit
+ JobConf conf = setupConf(QueueManager.toFullPropertyName(
+ "default", adminAcl), "dummy-user");
+ // Run job as ugi and try to kill job as user1, who (obviously)
+ // should not able to kill the job.
+ verifyJobKill(otherUGI, conf, false);
return null;
}
});
- }
+ }
public void testUserEnabledACLForJobKill()
throws IOException, LoginException, InterruptedException {
UserGroupInformation ugi = createNecessaryUsers();
-
+ // create other user who will try to kill the job of ugi.
+ final UserGroupInformation otherUGI = UserGroupInformation.
+ createUserForTesting("user1", new String [] {"group1"});
+
ugi.doAs(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
- // login as self...
UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
- String userName = ugi.getUserName();
- JobConf conf = setupConf("mapred.queue.default.acl-administer-jobs",
- "dummy-user,"+userName);
- verifyJobKillAsOtherUser(conf, true, "dummy-user,dummy-group");
+ String userName = ugi.getShortUserName();
+ JobConf conf = setupConf(QueueManager.toFullPropertyName(
+ "default", adminAcl), "user1");
+ // user1 should be able to kill the job
+ verifyJobKill(otherUGI, conf, true);
return null;
}
});
@@ -280,15 +324,18 @@ public class TestQueueManager extends Te
public void testUserDisabledForJobPriorityChange()
throws IOException, InterruptedException {
UserGroupInformation ugi = createNecessaryUsers();
+ // create other user who will try to change priority of the job of ugi.
+ final UserGroupInformation otherUGI = UserGroupInformation.
+ createUserForTesting("user1", new String [] {"group1"});
+
ugi.doAs(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
- JobConf conf = setupConf("mapred.queue.default.acl-administer-jobs",
- "junk-user");
- verifyJobPriorityChangeAsOtherUser(conf, false,
- "junk-user,dummy-group");
+ JobConf conf = setupConf(QueueManager.toFullPropertyName(
+ "default", adminAcl), "junk-user");
+ verifyJobPriorityChangeAsOtherUser(otherUGI, conf, false);
return null;
}
});
@@ -310,23 +357,29 @@ public class TestQueueManager extends Te
Properties hadoopConfProps = new Properties();
//these properties should be retained.
hadoopConfProps.put("mapred.queue.names", "default,q1,q2");
- hadoopConfProps.put("mapred.acls.enabled", "true");
+ hadoopConfProps.put(JobConf.MR_ACLS_ENABLED, "true");
//These property should always be overridden
- hadoopConfProps.put("mapred.queue.default.acl-submit-job", "u1");
- hadoopConfProps.put("mapred.queue.q1.acl-submit-job", "u2");
- hadoopConfProps.put("mapred.queue.q2.acl-submit-job", "u1");
+ hadoopConfProps.put(QueueManager.toFullPropertyName(
+ "default", submitAcl), "u1");
+ hadoopConfProps.put(QueueManager.toFullPropertyName(
+ "q1", submitAcl), "u2");
+ hadoopConfProps.put(QueueManager.toFullPropertyName(
+ "q2", submitAcl), "u1");
UtilsForTests.setUpConfigFile(hadoopConfProps, hadoopConfigFile);
//Actual property which would be used.
Properties queueConfProps = new Properties();
- queueConfProps.put("mapred.queue.default.acl-submit-job", " ");
+ queueConfProps.put(QueueManager.toFullPropertyName(
+ "default", submitAcl), " ");
//Writing out the queue configuration file.
UtilsForTests.setUpConfigFile(queueConfProps, queueConfigFile);
//Create a new configuration to be used with QueueManager
JobConf conf = new JobConf();
QueueManager queueManager = new QueueManager(conf);
- UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
+ UserGroupInformation ugi = UserGroupInformation.
+ createUserForTesting("user1", new String [] {"group1"});
+
//Job Submission should fail because ugi to be used is set to blank.
assertFalse("User Job Submission Succeeded before refresh.",
queueManager.hasAccess("default", QueueManager.QueueOperation.
@@ -345,10 +398,16 @@ public class TestQueueManager extends Te
queueManager.hasAccess("q2", QueueManager.QueueOperation.
SUBMIT_JOB, alternateUgi));
- //Set acl for the current user.
- queueConfProps.put("mapred.queue.default.acl-submit-job", ugi.getUserName());
- queueConfProps.put("mapred.queue.q1.acl-submit-job", ugi.getUserName());
- queueConfProps.put("mapred.queue.q2.acl-submit-job", ugi.getUserName());
+ //Set acl for user1.
+ queueConfProps.put(QueueManager.toFullPropertyName(
+ "default", submitAcl),
+ ugi.getShortUserName());
+ queueConfProps.put(QueueManager.toFullPropertyName(
+ "q1", submitAcl),
+ ugi.getShortUserName());
+ queueConfProps.put(QueueManager.toFullPropertyName(
+ "q2", submitAcl),
+ ugi.getShortUserName());
//write out queue-acls.xml.
UtilsForTests.setUpConfigFile(queueConfProps, queueConfigFile);
//refresh configuration
@@ -370,8 +429,10 @@ public class TestQueueManager extends Te
queueConfigFile.delete();
//rewrite the mapred-site.xml
- hadoopConfProps.put("mapred.acls.enabled", "true");
- hadoopConfProps.put("mapred.queue.default.acl-submit-job", ugi.getUserName());
+ hadoopConfProps.put(JobConf.MR_ACLS_ENABLED, "true");
+ hadoopConfProps.put(QueueManager.toFullPropertyName(
+ "default", submitAcl),
+ ugi.getShortUserName());
UtilsForTests.setUpConfigFile(hadoopConfProps, hadoopConfigFile);
queueManager.refreshAcls(conf);
assertTrue("User Job Submission failed after refresh and no queue acls file.",
@@ -397,15 +458,21 @@ public class TestQueueManager extends Te
// queue properties with which the cluster is started.
Properties hadoopConfProps = new Properties();
hadoopConfProps.put("mapred.queue.names", "default,q1,q2");
- hadoopConfProps.put("mapred.acls.enabled", "true");
+ hadoopConfProps.put(JobConf.MR_ACLS_ENABLED, "true");
UtilsForTests.setUpConfigFile(hadoopConfProps, hadoopConfigFile);
//properties for mapred-queue-acls.xml
Properties queueConfProps = new Properties();
UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
- queueConfProps.put("mapred.queue.default.acl-submit-job", ugi.getUserName());
- queueConfProps.put("mapred.queue.q1.acl-submit-job", ugi.getUserName());
- queueConfProps.put("mapred.queue.q2.acl-submit-job", ugi.getUserName());
+ queueConfProps.put(QueueManager.toFullPropertyName(
+ "default", submitAcl),
+ ugi.getShortUserName());
+ queueConfProps.put(QueueManager.toFullPropertyName(
+ "q1", submitAcl),
+ ugi.getShortUserName());
+ queueConfProps.put(QueueManager.toFullPropertyName(
+ "q2", submitAcl),
+ ugi.getShortUserName());
UtilsForTests.setUpConfigFile(queueConfProps, queueConfigFile);
Configuration conf = new JobConf();
@@ -457,7 +524,7 @@ public class TestQueueManager extends Te
private JobConf setupConf(String aclName, String aclValue) {
JobConf conf = new JobConf();
- conf.setBoolean("mapred.acls.enabled", true);
+ conf.setBoolean(JobConf.MR_ACLS_ENABLED, true);
conf.set(aclName, aclValue);
return conf;
}
@@ -470,21 +537,30 @@ public class TestQueueManager extends Te
}
}
- private void verifyJobSubmission(JobConf conf, boolean shouldSucceed)
- throws IOException, InterruptedException {
- verifyJobSubmission(conf, shouldSucceed, "default");
+ /**
+ * Verify job submission as given user to the default queue
+ */
+ private void verifyJobSubmissionToDefaultQueue(JobConf conf, boolean shouldSucceed,
+ String userInfo) throws IOException, InterruptedException {
+ verifyJobSubmission(conf, shouldSucceed, userInfo, "default");
}
+ /**
+ * Verify job submission as given user to the given queue
+ */
private void verifyJobSubmission(JobConf conf, boolean shouldSucceed,
- String queue) throws IOException, InterruptedException {
+ String userInfo, String queue) throws IOException, InterruptedException {
setUpCluster(conf);
try {
- runAndVerifySubmission(conf, shouldSucceed, queue, null);
+ runAndVerifySubmission(conf, shouldSucceed, queue, userInfo);
} finally {
tearDownCluster();
}
}
+ /**
+ * Verify if submission of job to the given queue will succeed or not
+ */
private void runAndVerifySubmission(JobConf conf, boolean shouldSucceed,
String queue, String userInfo)
throws IOException, InterruptedException {
@@ -519,8 +595,16 @@ public class TestQueueManager extends Te
}
}
- private void verifyJobKill(JobConf conf, boolean shouldSucceed)
- throws IOException, InterruptedException {
+ /**
+ * Submit job as current user and kill the job as user of ugi.
+ * @param ugi {@link UserGroupInformation} of user who tries to kill the job
+ * @param conf JobConf for the job
+ * @param shouldSucceed Should the killing of job be succeeded ?
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ private void verifyJobKill(UserGroupInformation ugi, JobConf conf,
+ boolean shouldSucceed) throws IOException, InterruptedException {
setUpCluster(conf);
try {
RunningJob rjob = submitSleepJob(1, 1, 1000, 1000, false);
@@ -532,7 +616,20 @@ public class TestQueueManager extends Te
break;
}
}
- rjob.killJob();
+ conf.set("mapred.job.tracker", "localhost:"
+ + miniMRCluster.getJobTrackerPort());
+ final String jobId = rjob.getJobID();
+ ugi.doAs(new PrivilegedExceptionAction<Object>() {
+
+ @Override
+ public Object run() throws Exception {
+ RunningJob runningJob =
+ new JobClient(miniMRCluster.createJobConf()).getJob(jobId);
+ runningJob.killJob();
+ return null;
+ }
+ });
+
while(rjob.cleanupProgress() == 0.0f) {
try {
Thread.sleep(10);
@@ -549,10 +646,9 @@ public class TestQueueManager extends Te
if (shouldSucceed) {
throw ioe;
} else {
- LOG.info("exception while submitting job: " + ioe.getMessage());
+ LOG.info("exception while submitting/killing job: " + ioe.getMessage());
assertTrue(ioe.getMessage().
- contains("cannot perform operation " +
- "ADMINISTER_JOBS on queue default"));
+ contains(" cannot perform operation MODIFY_JOB on "));
}
} finally {
tearDownCluster();
@@ -584,7 +680,7 @@ public class TestQueueManager extends Te
throw ioe;
}
//verify it fails
- LOG.info("exception while submitting job: " + ioe.getMessage());
+ LOG.info("exception while killing job: " + ioe.getMessage());
assertTrue(ioe.getMessage().
contains("cannot perform operation " +
"ADMINISTER_JOBS on queue default"));
@@ -602,32 +698,51 @@ public class TestQueueManager extends Te
}
}
- private void verifyJobPriorityChangeAsOtherUser(JobConf conf,
- boolean shouldSucceed, String otherUserInfo)
- throws IOException, InterruptedException {
+ /**
+ * Submit job as current user and try to change priority of that job as
+ * another user.
+ * @param otherUGI user who will try to change priority of job
+ * @param conf jobConf for the job
+ * @param shouldSucceed Should the changing of priority of job be succeeded ?
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ private void verifyJobPriorityChangeAsOtherUser(UserGroupInformation otherUGI,
+ JobConf conf, final boolean shouldSucceed)
+ throws IOException, InterruptedException {
setUpCluster(conf);
try {
- // submit job as another user.
- String userInfo = otherUserInfo;
- RunningJob rjob = submitSleepJob(1, 1, 1000, 1000, false, userInfo);
+ // submit job as current user.
+ UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
+ String[] groups = ugi.getGroupNames();
+ String userInfo = ugi.getShortUserName() + "," +
+ groups[groups.length - 1];
+ final RunningJob rjob = submitSleepJob(1, 1, 1000, 1000, false, userInfo);
assertFalse(rjob.isComplete());
- // try to change priority as self
- try {
- conf.set("mapred.job.tracker", "localhost:"
- + miniMRCluster.getJobTrackerPort());
- JobClient client = new JobClient(miniMRCluster.createJobConf());
- client.getJob(rjob.getID()).setJobPriority("VERY_LOW");
- if (!shouldSucceed) {
- fail("changing priority should fail.");
+ conf.set("mapred.job.tracker", "localhost:"
+ + miniMRCluster.getJobTrackerPort());
+ // try to change priority as other user
+ otherUGI.doAs(new PrivilegedExceptionAction<Object>() {
+
+ @Override
+ public Object run() throws Exception {
+ try {
+ JobClient client = new JobClient(miniMRCluster.createJobConf());
+ client.getJob(rjob.getID()).setJobPriority("VERY_LOW");
+ if (!shouldSucceed) {
+ fail("changing priority should fail.");
+ }
+ } catch (IOException ioe) {
+ //verify it fails
+ LOG.info("exception while changing priority of job: " +
+ ioe.getMessage());
+ assertTrue(ioe.getMessage().
+ contains(" cannot perform operation MODIFY_JOB on "));
+ }
+ return null;
}
- } catch (IOException ioe) {
- //verify it fails
- LOG.info("exception while submitting job: " + ioe.getMessage());
- assertTrue(ioe.getMessage().
- contains("cannot perform operation " +
- "ADMINISTER_JOBS on queue default"));
- }
+ });
//wait for job to complete on its own
while (!rjob.isComplete()) {
try {
Modified: hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestRecoveryManager.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestRecoveryManager.java?rev=1077423&r1=1077422&r2=1077423&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestRecoveryManager.java (original)
+++ hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestRecoveryManager.java Fri Mar 4 04:13:26 2011
@@ -31,6 +31,7 @@ import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.mapred.MiniMRCluster.JobTrackerRunner;
+import org.apache.hadoop.mapred.QueueManager.QueueOperation;
import org.apache.hadoop.mapred.TestJobInProgressListener.MyScheduler;
import org.apache.hadoop.security.UserGroupInformation;
import org.junit.*;
@@ -233,10 +234,11 @@ public class TestRecoveryManager extends
true);
mr.getJobTrackerConf().setInt("mapred.jobtracker.maxtasks.per.job", 25);
- mr.getJobTrackerConf().setBoolean("mapred.acls.enabled" , true);
+ mr.getJobTrackerConf().setBoolean(JobConf.MR_ACLS_ENABLED, true);
UserGroupInformation ugi = UserGroupInformation.getLoginUser();
- mr.getJobTrackerConf().set("mapred.queue.default.acl-submit-job",
- ugi.getUserName());
+ mr.getJobTrackerConf().set(QueueManager.toFullPropertyName(
+ "default", QueueOperation.SUBMIT_JOB.getAclName()),
+ ugi.getUserName());
// start the jobtracker
LOG.info("Starting jobtracker");
Modified: hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestTaskTrackerLocalization.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestTaskTrackerLocalization.java?rev=1077423&r1=1077422&r2=1077423&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestTaskTrackerLocalization.java (original)
+++ hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestTaskTrackerLocalization.java Fri Mar 4 04:13:26 2011
@@ -116,6 +116,7 @@ public class TestTaskTrackerLocalization
localDirs[i] = new File(ROOT_MAPRED_LOCAL_DIR, "0_" + i).getPath();
}
trackerFConf.setStrings("mapred.local.dir", localDirs);
+ trackerFConf.setBoolean(JobConf.MR_ACLS_ENABLED, true);
// Create the job configuration file. Same as trackerConf in this test.
jobConf = new JobConf(trackerFConf);
Modified: hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestWebUIAuthorization.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestWebUIAuthorization.java?rev=1077423&r1=1077422&r2=1077423&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestWebUIAuthorization.java (original)
+++ hadoop/common/branches/branch-0.20-security-patches/src/test/org/apache/hadoop/mapred/TestWebUIAuthorization.java Fri Mar 4 04:13:26 2011
@@ -33,6 +33,7 @@ import org.apache.hadoop.fs.Path;
import org.apache.hadoop.http.TestHttpServer.DummyFilterInitializer;
import org.apache.hadoop.mapred.JobHistory.Keys;
import org.apache.hadoop.mapred.JobHistory.TaskAttempt;
+import org.apache.hadoop.mapred.QueueManager.QueueOperation;
import org.apache.hadoop.mapreduce.JobContext;
import org.apache.hadoop.examples.SleepJob;
import org.apache.hadoop.security.Groups;
@@ -58,6 +59,8 @@ public class TestWebUIAuthorization exte
private static String mrOwner = null;
// member of supergroup
private static final String superGroupMember = "user2";
+ // admin of "default" queue
+ private static final String qAdmin = "user3";
// "colleague1" is there in job-view-acls config
private static final String viewColleague = "colleague1";
// "colleague2" is there in job-modify-acls config
@@ -107,42 +110,44 @@ public class TestWebUIAuthorization exte
* Validates the given jsp/servlet against different user names who
* can(or cannot) view the job.
* (1) jobSubmitter can view the job
- * (2) superGroupMember can view the job
- * (3) user mentioned in job-view-acls should be able to view the job
- * (4) user mentioned in job-modify-acls but not in job-view-acls
+ * (2) superGroupMember can view any job
+ * (3) mrOwner can view any job
+ * (4) user mentioned in job-view-acls should be able to view the
+ * job irrespective of job-modify-acls.
+ * (5) user mentioned in job-modify-acls but not in job-view-acls
* cannot view the job
- * (5) other unauthorized users cannot view the job
+ * (6) other unauthorized users cannot view the job
*/
private void validateViewJob(String url, String method)
throws IOException {
- assertEquals("Incorrect return code for " + jobSubmitter,
+ assertEquals("Incorrect return code for job submitter " + jobSubmitter,
HttpURLConnection.HTTP_OK, getHttpStatusCode(url, jobSubmitter,
method));
- assertEquals("Incorrect return code for " + superGroupMember,
- HttpURLConnection.HTTP_OK, getHttpStatusCode(url, superGroupMember,
- method));
- assertEquals("Incorrect return code for " + mrOwner,
+ assertEquals("Incorrect return code for supergroup-member " +
+ superGroupMember, HttpURLConnection.HTTP_OK,
+ getHttpStatusCode(url, superGroupMember, method));
+ assertEquals("Incorrect return code for MR-owner " + mrOwner,
HttpURLConnection.HTTP_OK, getHttpStatusCode(url, mrOwner, method));
- assertEquals("Incorrect return code for " + viewColleague,
- HttpURLConnection.HTTP_OK, getHttpStatusCode(url, viewColleague,
- method));
- assertEquals("Incorrect return code for " + viewAndModifyColleague,
- HttpURLConnection.HTTP_OK, getHttpStatusCode(url,
- viewAndModifyColleague, method));
- assertEquals("Incorrect return code for " + modifyColleague,
- HttpURLConnection.HTTP_UNAUTHORIZED, getHttpStatusCode(url,
- modifyColleague, method));
- assertEquals("Incorrect return code for " + unauthorizedUser,
- HttpURLConnection.HTTP_UNAUTHORIZED, getHttpStatusCode(url,
- unauthorizedUser, method));
+ assertEquals("Incorrect return code for user in job-view-acl " +
+ viewColleague, HttpURLConnection.HTTP_OK,
+ getHttpStatusCode(url, viewColleague, method));
+ assertEquals("Incorrect return code for user in job-view-acl and " +
+ "job-modify-acl " + viewAndModifyColleague, HttpURLConnection.HTTP_OK,
+ getHttpStatusCode(url, viewAndModifyColleague, method));
+ assertEquals("Incorrect return code for user in job-modify-acl " +
+ modifyColleague, HttpURLConnection.HTTP_UNAUTHORIZED,
+ getHttpStatusCode(url, modifyColleague, method));
+ assertEquals("Incorrect return code for unauthorizedUser " +
+ unauthorizedUser, HttpURLConnection.HTTP_UNAUTHORIZED,
+ getHttpStatusCode(url, unauthorizedUser, method));
}
/**
* Validates the given jsp/servlet against different user names who
* can(or cannot) modify the job.
- * (1) jobSubmitter and superGroupMember can modify the job. But we are not
- * validating this in this method. Let the caller explicitly validate
- * this, if needed.
+ * (1) jobSubmitter, mrOwner, qAdmin and superGroupMember can modify the job.
+ * But we are not validating this in this method. Let the caller
+ * explicitly validate this, if needed.
* (2) user mentioned in job-view-acls but not in job-modify-acls cannot
* modify the job
* (3) user mentioned in job-modify-acls (irrespective of job-view-acls)
@@ -256,8 +261,11 @@ public class TestWebUIAuthorization exte
Properties props = new Properties();
props.setProperty("hadoop.http.filter.initializers",
DummyFilterInitializer.class.getName());
- props.setProperty(JobConf.JOB_LEVEL_AUTHORIZATION_ENABLING_FLAG,
- String.valueOf(true));
+
+ props.setProperty(JobConf.MR_ACLS_ENABLED, String.valueOf(true));
+ props.setProperty(QueueManager.toFullPropertyName(
+ "default", QueueOperation.ADMINISTER_JOBS.getAclName()), qAdmin);
+
props.setProperty("dfs.permissions", "false");
// Let us have history files on HDFS
@@ -272,9 +280,11 @@ public class TestWebUIAuthorization exte
MyGroupsProvider.mapping.put(unauthorizedUser, Arrays.asList("evilSociety"));
MyGroupsProvider.mapping.put(superGroupMember, Arrays.asList("superGroup"));
MyGroupsProvider.mapping.put(viewAndModifyColleague, Arrays.asList("group3"));
+ MyGroupsProvider.mapping.put(qAdmin, Arrays.asList("group4"));
+
mrOwner = UserGroupInformation.getCurrentUser().getShortUserName();
MyGroupsProvider.mapping.put(mrOwner, Arrays.asList(
- new String[] { "group4", "group5" }));
+ new String[] { "group5", "group6" }));
startCluster(true, props);
MiniMRCluster cluster = getMRCluster();
@@ -410,11 +420,13 @@ public class TestWebUIAuthorization exte
* (1) jobSubmitter, mrOwner and superGroupMember can do both view and modify
* on the job. But we are not validating this in this method. Let the
* caller explicitly validate this, if needed.
- * (2) user mentioned in job-view-acls but not in job-modify-acls cannot
+ * (2) user mentioned in job-view-acls and job-modify-acls can do this
+ * (3) user mentioned in job-view-acls but not in job-modify-acls cannot
* do this
- * (3) user mentioned in job-modify-acls but not in job-view-acls cannot
+ * (4) user mentioned in job-modify-acls but not in job-view-acls cannot
* do this
- * (4) other unauthorized users cannot do this
+ * (5) qAdmin cannot do this because he doesn't have view access to the job
+ * (6) other unauthorized users cannot do this
*
* @throws Exception
*/
@@ -441,11 +453,16 @@ public class TestWebUIAuthorization exte
getHttpStatusCode(url, unauthorizedUser, "POST"));
assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED,
getHttpStatusCode(url, modifyColleague, "POST"));
+ // As qAdmin doesn't have view access to job, he cannot kill the job
+ // from jobdetails web page. But qAdmin can kill job from jobtracker page.
+ assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED,
+ getHttpStatusCode(url, qAdmin, "POST"));
+
assertEquals(HttpURLConnection.HTTP_OK,
getHttpStatusCode(url, viewAndModifyColleague, "POST"));
waitForKillJobToFinish(job);
- assertTrue("killJob failed for a job for which user has "
- + "job-modify permission", job.isComplete());
+ assertTrue("killJob using jobdetails.jsp failed for a job for which "
+ + "user has job-view and job-modify permissions", job.isComplete());
} finally {
if (!job.isComplete()) {
LOG.info("Killing job " + jobid + " from finally block");
@@ -455,8 +472,8 @@ public class TestWebUIAuthorization exte
}
}
- // check if jobSubmitter, mrOwner and superGroupMember can do killJob
- // using jobdetails.jsp url
+ // check if jobSubmitter, mrOwner superGroupMember can do
+ // killJob using jobdetails.jsp url
confirmJobDetailsJSPKillJobAsUser(cluster, conf, jtURL, jobTrackerJSP,
jobSubmitter);
confirmJobDetailsJSPKillJobAsUser(cluster, conf, jtURL, jobTrackerJSP,
@@ -532,9 +549,10 @@ public class TestWebUIAuthorization exte
conf.set(JobContext.JOB_ACL_VIEW_JOB, "");
// Let us start 4 jobs as 4 different users(none of these 4 users is
- // mrOwner and none of these users is a member of superGroup). So only
- // based on the config JobContext.JOB_ACL_MODIFY_JOB being set here,
- // killJob on each of the jobs will be succeeded.
+ // mrOwner and none of these users is a member of superGroup and none of
+ // these 4 users is a queue admin for the default queue). So only
+ // based on the config JobContext.JOB_ACL_MODIFY_JOB being set here and the
+ // job-submitter, killJob on each of the jobs will be succeeded.
// start 1st job.
// Out of these 4 users, only jobSubmitter can do killJob on 1st job
@@ -603,8 +621,11 @@ public class TestWebUIAuthorization exte
Properties props = new Properties();
props.setProperty("hadoop.http.filter.initializers",
DummyFilterInitializer.class.getName());
- props.setProperty(
- JobConf.JOB_LEVEL_AUTHORIZATION_ENABLING_FLAG, String.valueOf(true));
+
+ props.setProperty(JobConf.MR_ACLS_ENABLED, String.valueOf(true));
+ props.setProperty(QueueManager.toFullPropertyName(
+ "default", QueueOperation.ADMINISTER_JOBS.getAclName()), qAdmin);
+
props.setProperty("dfs.permissions", "false");
// let us have enough map slots so that there won't be waiting for slots
props.setProperty("mapred.tasktracker.map.tasks.maximum", "6");
@@ -618,10 +639,11 @@ public class TestWebUIAuthorization exte
MyGroupsProvider.mapping.put(unauthorizedUser, Arrays.asList("evilSociety"));
MyGroupsProvider.mapping.put(superGroupMember, Arrays.asList("superGroup"));
MyGroupsProvider.mapping.put(viewAndModifyColleague, Arrays.asList("group3"));
+ MyGroupsProvider.mapping.put(qAdmin, Arrays.asList("group4"));
mrOwner = UserGroupInformation.getCurrentUser().getShortUserName();
MyGroupsProvider.mapping.put(mrOwner, Arrays.asList(
- new String[] { "group4", "group5" }));
+ new String[] { "group5", "group6" }));
startCluster(true, props);
MiniMRCluster cluster = getMRCluster();
@@ -676,8 +698,8 @@ public class TestWebUIAuthorization exte
viewAndModifyColleague);
confirmJobTrackerJSPKillJobAsUser(cluster, conf, jtURL, jobSubmitter);
confirmJobTrackerJSPKillJobAsUser(cluster, conf, jtURL, mrOwner);
- confirmJobTrackerJSPKillJobAsUser(cluster, conf, jtURL,
- superGroupMember);
+ confirmJobTrackerJSPKillJobAsUser(cluster, conf, jtURL, superGroupMember);
+ confirmJobTrackerJSPKillJobAsUser(cluster, conf, jtURL, qAdmin);
// validate killing of multiple jobs using jobtracker jsp and check
// if all the jobs which can be killed by user are actually the ones that
@@ -725,7 +747,7 @@ public class TestWebUIAuthorization exte
"&changeJobPriority=true&setJobPriority="+"HIGH"+"&jobCheckBox=" +
jobid.toString();
validateModifyJob(jobTrackerJSPSetJobPriorityAction, "GET");
- // jobSubmitter, mrOwner and superGroupMember are not validated for
+ // jobSubmitter, mrOwner, qAdmin and superGroupMember are not validated for
// job-modify permission in validateModifyJob(). So let us do it
// explicitly here
assertEquals(HttpURLConnection.HTTP_OK, getHttpStatusCode(
@@ -733,6 +755,8 @@ public class TestWebUIAuthorization exte
assertEquals(HttpURLConnection.HTTP_OK, getHttpStatusCode(
jobTrackerJSPSetJobPriorityAction, superGroupMember, "GET"));
assertEquals(HttpURLConnection.HTTP_OK, getHttpStatusCode(
+ jobTrackerJSPSetJobPriorityAction, qAdmin, "GET"));
+ assertEquals(HttpURLConnection.HTTP_OK, getHttpStatusCode(
jobTrackerJSPSetJobPriorityAction, mrOwner, "GET"));
}
@@ -808,6 +832,8 @@ public class TestWebUIAuthorization exte
assertEquals(HttpURLConnection.HTTP_OK,
getHttpStatusCode(jobTrackerJSP, mrOwner, "GET"));
assertEquals(HttpURLConnection.HTTP_OK,
+ getHttpStatusCode(jobTrackerJSP, qAdmin, "GET"));
+ assertEquals(HttpURLConnection.HTTP_OK,
getHttpStatusCode(jobTrackerJSP, superGroupMember, "GET"));
}
}