| /** |
| * 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.security.authorize; |
| |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.security.PrivilegedExceptionAction; |
| |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.fs.FileSystem; |
| import org.apache.hadoop.fs.FileUtil; |
| import org.apache.hadoop.fs.Path; |
| import org.apache.hadoop.hdfs.HDFSPolicyProvider; |
| import org.apache.hadoop.hdfs.MiniDFSCluster; |
| import org.apache.hadoop.hdfs.tools.DFSAdmin; |
| import org.apache.hadoop.ipc.RemoteException; |
| import org.apache.hadoop.mapred.JobConf; |
| import org.apache.hadoop.mapred.MiniMRCluster; |
| import org.apache.hadoop.mapred.TestMiniMRWithDFS; |
| import org.apache.hadoop.security.UserGroupInformation; |
| import org.apache.hadoop.util.StringUtils; |
| |
| import junit.framework.TestCase; |
| |
| public class TestServiceLevelAuthorization extends TestCase { |
| public void testServiceLevelAuthorization() throws Exception { |
| MiniDFSCluster dfs = null; |
| MiniMRCluster mr = null; |
| FileSystem fileSys = null; |
| try { |
| final int slaves = 4; |
| |
| // Turn on service-level authorization |
| Configuration conf = new Configuration(); |
| conf.setClass(PolicyProvider.POLICY_PROVIDER_CONFIG, |
| HadoopPolicyProvider.class, PolicyProvider.class); |
| conf.setBoolean(ServiceAuthorizationManager.SERVICE_AUTHORIZATION_CONFIG, |
| true); |
| |
| // Start the mini clusters |
| dfs = new MiniDFSCluster(conf, slaves, true, null); |
| fileSys = dfs.getFileSystem(); |
| JobConf mrConf = new JobConf(conf); |
| mr = new MiniMRCluster(slaves, fileSys.getUri().toString(), 1, |
| null, null, mrConf); |
| // make cleanup inline sothat validation of existence of these directories |
| // can be done |
| mr.setInlineCleanupThreads(); |
| |
| // Run examples |
| TestMiniMRWithDFS.runPI(mr, mr.createJobConf(mrConf)); |
| TestMiniMRWithDFS.runWordCount(mr, mr.createJobConf(mrConf)); |
| } finally { |
| if (dfs != null) { dfs.shutdown(); } |
| if (mr != null) { mr.shutdown(); |
| } |
| } |
| } |
| |
| private static final String DUMMY_ACL = "nouser nogroup"; |
| private static final String UNKNOWN_USER = "dev,null"; |
| |
| private void rewriteHadoopPolicyFile(File policyFile) throws IOException { |
| FileWriter fos = new FileWriter(policyFile); |
| PolicyProvider policyProvider = new HDFSPolicyProvider(); |
| fos.write("<configuration>\n"); |
| for (Service service : policyProvider.getServices()) { |
| String key = service.getServiceKey(); |
| String value ="*"; |
| if (key.equals("security.refresh.policy.protocol.acl")) { |
| value = DUMMY_ACL; |
| } |
| fos.write("<property><name>"+ key + "</name><value>" + value + |
| "</value></property>\n"); |
| System.err.println("<property><name>"+ key + "</name><value>" + value + |
| "</value></property>\n"); |
| } |
| fos.write("</configuration>\n"); |
| fos.close(); |
| } |
| |
| private void refreshPolicy(Configuration conf) throws IOException { |
| DFSAdmin dfsAdmin = new DFSAdmin(conf); |
| dfsAdmin.refreshServiceAcl(); |
| } |
| |
| public void testRefresh() throws Exception { |
| MiniDFSCluster dfs = null; |
| try { |
| final int slaves = 4; |
| |
| // Turn on service-level authorization |
| final Configuration conf = new Configuration(); |
| conf.setClass(PolicyProvider.POLICY_PROVIDER_CONFIG, |
| HDFSPolicyProvider.class, PolicyProvider.class); |
| conf.setBoolean(ServiceAuthorizationManager.SERVICE_AUTHORIZATION_CONFIG, |
| true); |
| |
| // Start the mini dfs cluster |
| dfs = new MiniDFSCluster(conf, slaves, true, null); |
| |
| // Refresh the service level authorization policy |
| refreshPolicy(conf); |
| |
| // Simulate an 'edit' of hadoop-policy.xml |
| String confDir = System.getProperty("test.build.extraconf", |
| "build/test/extraconf"); |
| String HADOOP_POLICY_FILE = System.getProperty("hadoop.policy.file"); |
| File policyFile = new File(confDir, HADOOP_POLICY_FILE); |
| String policyFileCopy = HADOOP_POLICY_FILE + ".orig"; |
| FileUtil.copy(policyFile, FileSystem.getLocal(conf), // first save original |
| new Path(confDir, policyFileCopy), false, conf); |
| rewriteHadoopPolicyFile( // rewrite the file |
| new File(confDir, HADOOP_POLICY_FILE)); |
| |
| // Refresh the service level authorization policy |
| refreshPolicy(conf); |
| |
| // Refresh the service level authorization policy once again, |
| // this time it should fail! |
| try { |
| // Note: hadoop-policy.xml for tests has |
| // security.refresh.policy.protocol.acl = ${user.name} |
| UserGroupInformation unknownUser = |
| UserGroupInformation.createRemoteUser("unknown"); |
| unknownUser.doAs(new PrivilegedExceptionAction<Void>() { |
| public Void run() throws IOException { |
| refreshPolicy(conf); |
| return null; |
| } |
| }); |
| fail("Refresh of NameNode's policy file cannot be successful!"); |
| } catch (Exception re) { |
| System.out.println("Good, refresh worked... refresh failed with: " + |
| StringUtils.stringifyException(re)); |
| } finally { |
| // Reset to original hadoop-policy.xml |
| FileUtil.fullyDelete(new File(confDir, |
| HADOOP_POLICY_FILE)); |
| FileUtil.replaceFile(new File(confDir, policyFileCopy), new File(confDir, HADOOP_POLICY_FILE)); |
| } |
| } finally { |
| if (dfs != null) { dfs.shutdown(); } |
| } |
| } |
| |
| } |