1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package org.apache.hadoop.fs; 20 21 import java.io.IOException; 22 import java.net.URISyntaxException; 23 24 import javax.security.auth.login.LoginException; 25 26 import org.apache.hadoop.conf.Configuration; 27 import org.apache.hadoop.fs.permission.FsPermission; 28 import org.apache.hadoop.fs.CommonConfigurationKeys; 29 import org.apache.hadoop.hdfs.HdfsConfiguration; 30 import org.apache.hadoop.hdfs.MiniDFSCluster; 31 import org.apache.hadoop.security.UserGroupInformation; 32 import org.apache.hadoop.util.StringUtils; 33 import static org.apache.hadoop.fs.FileContextTestHelper.*; 34 import org.apache.commons.logging.impl.Log4JLogger; 35 import org.apache.log4j.Level; 36 import org.junit.After; 37 import org.junit.AfterClass; 38 import org.junit.Assert; 39 import org.junit.Before; 40 import org.junit.BeforeClass; 41 import org.junit.Test; 42 43 public class TestFcHdfsSetUMask { 44 45 private static final FileContextTestHelper fileContextTestHelper = 46 new FileContextTestHelper("/tmp/TestFcHdfsSetUMask"); 47 private static MiniDFSCluster cluster; 48 private static Path defaultWorkingDirectory; 49 private static FileContext fc; 50 51 // rwxrwx--- 52 private static final FsPermission USER_GROUP_OPEN_PERMISSIONS = FsPermission 53 .createImmutable((short) 0770); 54 55 private static final FsPermission USER_GROUP_OPEN_FILE_PERMISSIONS = 56 FsPermission.createImmutable((short) 0660); 57 58 private static final FsPermission USER_GROUP_OPEN_TEST_UMASK = FsPermission 59 .createImmutable((short) (0770 ^ 0777)); 60 61 // --------- 62 private static final FsPermission BLANK_PERMISSIONS = FsPermission 63 .createImmutable((short) 0000); 64 65 // parent directory permissions when creating a directory with blank (000) 66 // permissions - it always add the -wx------ bits to the parent so that 67 // it can create the child 68 private static final FsPermission PARENT_PERMS_FOR_BLANK_PERMISSIONS = 69 FsPermission.createImmutable((short) 0300); 70 71 private static final FsPermission BLANK_TEST_UMASK = FsPermission 72 .createImmutable((short) (0000 ^ 0777)); 73 74 // rwxrwxrwx 75 private static final FsPermission WIDE_OPEN_PERMISSIONS = FsPermission 76 .createImmutable((short) 0777); 77 78 private static final FsPermission WIDE_OPEN_FILE_PERMISSIONS = 79 FsPermission.createImmutable((short) 0666); 80 81 private static final FsPermission WIDE_OPEN_TEST_UMASK = FsPermission 82 .createImmutable((short) (0777 ^ 0777)); 83 84 @BeforeClass clusterSetupAtBegining()85 public static void clusterSetupAtBegining() 86 throws IOException, LoginException, URISyntaxException { 87 Configuration conf = new HdfsConfiguration(); 88 // set permissions very restrictive 89 conf.set(CommonConfigurationKeys.FS_PERMISSIONS_UMASK_KEY, "077"); 90 cluster = new MiniDFSCluster.Builder(conf).numDataNodes(2).build(); 91 fc = FileContext.getFileContext(cluster.getURI(0), conf); 92 defaultWorkingDirectory = fc.makeQualified( new Path("/user/" + 93 UserGroupInformation.getCurrentUser().getShortUserName())); 94 fc.mkdir(defaultWorkingDirectory, FileContext.DEFAULT_PERM, true); 95 } 96 97 @AfterClass ClusterShutdownAtEnd()98 public static void ClusterShutdownAtEnd() throws Exception { 99 cluster.shutdown(); 100 } 101 102 { 103 try { 104 ((Log4JLogger)FileSystem.LOG).getLogger().setLevel(Level.DEBUG); 105 } 106 catch(Exception e) { 107 System.out.println("Cannot change log level\n" 108 + StringUtils.stringifyException(e)); 109 } 110 } 111 112 @Before setUp()113 public void setUp() throws Exception { 114 fc.setUMask(WIDE_OPEN_TEST_UMASK); 115 fc.mkdir(fileContextTestHelper.getTestRootPath(fc), FileContext.DEFAULT_PERM, true); 116 } 117 118 @After tearDown()119 public void tearDown() throws Exception { 120 fc.delete(fileContextTestHelper.getTestRootPath(fc), true); 121 } 122 123 @Test testMkdirWithExistingDirClear()124 public void testMkdirWithExistingDirClear() throws IOException { 125 testMkdirWithExistingDir(BLANK_TEST_UMASK, BLANK_PERMISSIONS); 126 } 127 128 @Test testMkdirWithExistingDirOpen()129 public void testMkdirWithExistingDirOpen() throws IOException { 130 testMkdirWithExistingDir(WIDE_OPEN_TEST_UMASK, WIDE_OPEN_PERMISSIONS); 131 } 132 133 @Test testMkdirWithExistingDirMiddle()134 public void testMkdirWithExistingDirMiddle() throws IOException { 135 testMkdirWithExistingDir(USER_GROUP_OPEN_TEST_UMASK, 136 USER_GROUP_OPEN_PERMISSIONS); 137 } 138 139 @Test testMkdirRecursiveWithNonExistingDirClear()140 public void testMkdirRecursiveWithNonExistingDirClear() throws IOException { 141 // by default parent directories have -wx------ bits set 142 testMkdirRecursiveWithNonExistingDir(BLANK_TEST_UMASK, BLANK_PERMISSIONS, 143 PARENT_PERMS_FOR_BLANK_PERMISSIONS); 144 } 145 146 @Test testMkdirRecursiveWithNonExistingDirOpen()147 public void testMkdirRecursiveWithNonExistingDirOpen() throws IOException { 148 testMkdirRecursiveWithNonExistingDir(WIDE_OPEN_TEST_UMASK, 149 WIDE_OPEN_PERMISSIONS, WIDE_OPEN_PERMISSIONS); 150 } 151 152 @Test testMkdirRecursiveWithNonExistingDirMiddle()153 public void testMkdirRecursiveWithNonExistingDirMiddle() throws IOException { 154 testMkdirRecursiveWithNonExistingDir(USER_GROUP_OPEN_TEST_UMASK, 155 USER_GROUP_OPEN_PERMISSIONS, USER_GROUP_OPEN_PERMISSIONS); 156 } 157 158 159 @Test testCreateRecursiveWithExistingDirClear()160 public void testCreateRecursiveWithExistingDirClear() throws IOException { 161 testCreateRecursiveWithExistingDir(BLANK_TEST_UMASK, BLANK_PERMISSIONS); 162 } 163 164 @Test testCreateRecursiveWithExistingDirOpen()165 public void testCreateRecursiveWithExistingDirOpen() throws IOException { 166 testCreateRecursiveWithExistingDir(WIDE_OPEN_TEST_UMASK, 167 WIDE_OPEN_FILE_PERMISSIONS); 168 } 169 170 @Test testCreateRecursiveWithExistingDirMiddle()171 public void testCreateRecursiveWithExistingDirMiddle() throws IOException { 172 testCreateRecursiveWithExistingDir(USER_GROUP_OPEN_TEST_UMASK, 173 USER_GROUP_OPEN_FILE_PERMISSIONS); 174 } 175 176 177 @Test testCreateRecursiveWithNonExistingDirClear()178 public void testCreateRecursiveWithNonExistingDirClear() throws IOException { 179 // directory permission inherited from parent so this must match the @Before 180 // set of umask 181 testCreateRecursiveWithNonExistingDir(BLANK_TEST_UMASK, 182 WIDE_OPEN_PERMISSIONS, BLANK_PERMISSIONS); 183 } 184 185 @Test testCreateRecursiveWithNonExistingDirOpen()186 public void testCreateRecursiveWithNonExistingDirOpen() throws IOException { 187 // directory permission inherited from parent so this must match the @Before 188 // set of umask 189 testCreateRecursiveWithNonExistingDir(WIDE_OPEN_TEST_UMASK, 190 WIDE_OPEN_PERMISSIONS, WIDE_OPEN_FILE_PERMISSIONS); 191 } 192 193 @Test testCreateRecursiveWithNonExistingDirMiddle()194 public void testCreateRecursiveWithNonExistingDirMiddle() throws IOException { 195 // directory permission inherited from parent so this must match the @Before 196 // set of umask 197 testCreateRecursiveWithNonExistingDir(USER_GROUP_OPEN_TEST_UMASK, 198 WIDE_OPEN_PERMISSIONS, USER_GROUP_OPEN_FILE_PERMISSIONS); 199 } 200 201 testMkdirWithExistingDir(FsPermission umask, FsPermission expectedPerms)202 public void testMkdirWithExistingDir(FsPermission umask, 203 FsPermission expectedPerms) throws IOException { 204 Path f = fileContextTestHelper.getTestRootPath(fc, "aDir"); 205 fc.setUMask(umask); 206 fc.mkdir(f, FileContext.DEFAULT_PERM, true); 207 Assert.assertTrue(isDir(fc, f)); 208 Assert.assertEquals("permissions on directory are wrong", 209 expectedPerms, fc.getFileStatus(f).getPermission()); 210 } 211 testMkdirRecursiveWithNonExistingDir(FsPermission umask, FsPermission expectedPerms, FsPermission expectedParentPerms)212 public void testMkdirRecursiveWithNonExistingDir(FsPermission umask, 213 FsPermission expectedPerms, FsPermission expectedParentPerms) 214 throws IOException { 215 Path f = fileContextTestHelper.getTestRootPath(fc, "NonExistant2/aDir"); 216 fc.setUMask(umask); 217 fc.mkdir(f, FileContext.DEFAULT_PERM, true); 218 Assert.assertTrue(isDir(fc, f)); 219 Assert.assertEquals("permissions on directory are wrong", 220 expectedPerms, fc.getFileStatus(f).getPermission()); 221 Path fParent = fileContextTestHelper.getTestRootPath(fc, "NonExistant2"); 222 Assert.assertEquals("permissions on parent directory are wrong", 223 expectedParentPerms, fc.getFileStatus(fParent).getPermission()); 224 } 225 226 testCreateRecursiveWithExistingDir(FsPermission umask, FsPermission expectedPerms)227 public void testCreateRecursiveWithExistingDir(FsPermission umask, 228 FsPermission expectedPerms) throws IOException { 229 Path f = fileContextTestHelper.getTestRootPath(fc,"foo"); 230 fc.setUMask(umask); 231 createFile(fc, f); 232 Assert.assertTrue(isFile(fc, f)); 233 Assert.assertEquals("permissions on file are wrong", 234 expectedPerms , fc.getFileStatus(f).getPermission()); 235 } 236 237 testCreateRecursiveWithNonExistingDir(FsPermission umask, FsPermission expectedDirPerms, FsPermission expectedFilePerms)238 public void testCreateRecursiveWithNonExistingDir(FsPermission umask, 239 FsPermission expectedDirPerms, FsPermission expectedFilePerms) 240 throws IOException { 241 Path f = fileContextTestHelper.getTestRootPath(fc,"NonExisting/foo"); 242 Path fParent = fileContextTestHelper.getTestRootPath(fc, "NonExisting"); 243 Assert.assertFalse(exists(fc, fParent)); 244 fc.setUMask(umask); 245 createFile(fc, f); 246 Assert.assertTrue(isFile(fc, f)); 247 Assert.assertEquals("permissions on file are wrong", 248 expectedFilePerms, fc.getFileStatus(f).getPermission()); 249 Assert.assertEquals("permissions on parent directory are wrong", 250 expectedDirPerms, fc.getFileStatus(fParent).getPermission()); 251 } 252 253 } 254