/** * Changes the mode of an Alluxio file. * * @param path the path of the file * @param mode the mode to change to * @return 0 on success, a negative value on error */ @Override public int chmod(String path, @mode_t long mode) { AlluxioURI uri = mPathResolverCache.getUnchecked(path); SetAttributePOptions options = SetAttributePOptions.newBuilder() .setMode(new alluxio.security.authorization.Mode((short) mode).toProto()).build(); try { mFileSystem.setAttribute(uri, options); } catch (Throwable t) { LOG.error("Failed to change {} to mode {}", path, mode, t); return AlluxioFuseUtils.getErrorCode(t); } return 0; }
/** * Changes permission of a path. * * @param path path to set permission * @param permission permission set to path */ @Override public void setPermission(Path path, FsPermission permission) throws IOException { LOG.debug("setMode({},{})", path, permission.toString()); AlluxioURI uri = new AlluxioURI(HadoopUtils.getPathWithoutScheme(path)); SetAttributePOptions options = SetAttributePOptions.newBuilder() .setMode(new Mode(permission.toShort()).toProto()).setRecursive(false).build(); try { mFileSystem.setAttribute(uri, options); } catch (AlluxioException e) { throw new IOException(e); } }
@Test public void setAclWithoutOwner() throws Exception { createFileWithSingleBlock(NESTED_FILE_URI); mFileSystemMaster.setAttribute(NESTED_URI, SetAttributeContext .defaults(SetAttributePOptions.newBuilder().setMode(new Mode((short) 0777).toProto()))); Set<String> entries = Sets.newHashSet(mFileSystemMaster .getFileInfo(NESTED_FILE_URI, GET_STATUS_CONTEXT).convertAclToStringEntries()); assertEquals(3, entries.size()); try (AuthenticatedClientUserResource userA = new AuthenticatedClientUserResource("userA", ServerConfiguration.global())) { Set<String> newEntries = Sets.newHashSet("user::rwx", "group::rwx", "other::rwx"); mThrown.expect(AccessControlException.class); mFileSystemMaster.setAcl(NESTED_FILE_URI, SetAclAction.REPLACE, newEntries.stream().map(AclEntry::fromCliString).collect(Collectors.toList()), SetAclContext.defaults()); } }
setAttributeSingleFile(rpcContext, inodePath, false, opTimeMs, SetAttributeContext .defaults(SetAttributePOptions.newBuilder().setOwner(ufsFpParsed.getTag(Tag.OWNER)) .setGroup(ufsFpParsed.getTag(Tag.GROUP)).setMode(new Mode(mode).toProto())) .setUfsFingerprint(ufsFingerprint));
private void verifySetAcl(TestUser runUser, String path, String owner, String group, short mode, boolean recursive) throws Exception { try (Closeable r = new AuthenticatedUserRule(runUser.getUser(), ServerConfiguration.global()).toResource()) { SetAttributeContext context = SetAttributeContext.defaults(SetAttributePOptions.newBuilder() .setMode(new Mode(mode).toProto()).setRecursive(recursive)); if (owner != null) { context.getOptions().setOwner(owner); } if (group != null) { context.getOptions().setGroup(group); } mFileSystemMaster.setAttribute(new AlluxioURI(path), context); } try (Closeable r = new AuthenticatedUserRule(TEST_USER_ADMIN.getUser(), ServerConfiguration.global()).toResource()) { FileInfo fileInfo = mFileSystemMaster.getFileInfo(mFileSystemMaster.getFileId(new AlluxioURI(path))); if (owner != null) { assertEquals(owner, fileInfo.getOwner()); } if (group != null) { assertEquals(group, fileInfo.getGroup()); } if (mode != -1) { assertEquals(mode, fileInfo.getMode()); } } }
@Test public void listStatusRecursivePermissions() throws Exception { final int files = 10; List<FileInfo> infos; List<String> filenames; // Test files in root directory. for (int i = 0; i < files; i++) { createFileWithSingleBlock(ROOT_URI.join("file" + String.format("%05d", i))); } // Test files in nested directory. for (int i = 0; i < files; i++) { createFileWithSingleBlock(NESTED_URI.join("file" + String.format("%05d", i))); } // Test with permissions mFileSystemMaster.setAttribute(NESTED_URI, SetAttributeContext.defaults(SetAttributePOptions .newBuilder().setMode(new Mode((short) 0400).toProto()).setRecursive(true))); try (Closeable r = new AuthenticatedUserRule("test_user1", ServerConfiguration.global()) .toResource()) { // Test recursive listStatus infos = mFileSystemMaster.listStatus(ROOT_URI, ListStatusContext.defaults(ListStatusPOptions .newBuilder().setLoadMetadataType(LoadMetadataPType.ALWAYS).setRecursive(true))); // 10 files in each directory, 1 level of directories assertEquals(files + 1, infos.size()); } }
@Test public void deleteDirRecursiveWithInsufficientPermissions() throws Exception { // userA has permissions to delete directory but not one of the nested files createFileWithSingleBlock(NESTED_FILE_URI); createFileWithSingleBlock(NESTED_FILE2_URI); mFileSystemMaster.setAttribute(NESTED_URI, SetAttributeContext .defaults(SetAttributePOptions.newBuilder().setMode(new Mode((short) 0777).toProto()))); mFileSystemMaster.setAttribute(NESTED_FILE_URI, SetAttributeContext .defaults(SetAttributePOptions.newBuilder().setMode(new Mode((short) 0700).toProto()))); mFileSystemMaster.setAttribute(NESTED_FILE2_URI, SetAttributeContext .defaults(SetAttributePOptions.newBuilder().setMode(new Mode((short) 0777).toProto()))); try (AuthenticatedClientUserResource userA = new AuthenticatedClientUserResource("userA", ServerConfiguration.global())) { mFileSystemMaster.delete(NESTED_URI, DeleteContext.defaults(DeletePOptions.newBuilder().setRecursive(true))); fail("Deleting a directory w/ insufficient permission on child should fail"); } catch (AccessControlException e) { String expectedChildMessage = ExceptionMessage.PERMISSION_DENIED .getMessage("user=userA, access=-w-, path=" + NESTED_FILE_URI + ": failed at file"); assertTrue(e.getMessage().startsWith(ExceptionMessage.DELETE_FAILED_DIR_CHILDREN .getMessage(NESTED_URI, expectedChildMessage))); } assertNotEquals(IdUtils.INVALID_FILE_ID, mFileSystemMaster.getFileId(NESTED_URI)); assertNotEquals(IdUtils.INVALID_FILE_ID, mFileSystemMaster.getFileId(NESTED_FILE_URI)); assertNotEquals(IdUtils.INVALID_FILE_ID, mFileSystemMaster.getFileId(NESTED_FILE2_URI)); }
@Test public void setAclNestedWithoutOwner() throws Exception { createFileWithSingleBlock(NESTED_FILE_URI); mFileSystemMaster.setAttribute(NESTED_URI, SetAttributeContext.defaults(SetAttributePOptions .newBuilder().setMode(new Mode((short) 0777).toProto()).setOwner("userA"))); Set<String> entries = Sets.newHashSet(mFileSystemMaster .getFileInfo(NESTED_FILE_URI, GET_STATUS_CONTEXT).convertAclToStringEntries()); assertEquals(3, entries.size()); // recursive setAcl should fail if one of the child is not owned by the user mThrown.expect(AccessControlException.class); try (AuthenticatedClientUserResource userA = new AuthenticatedClientUserResource("userA", ServerConfiguration.global())) { Set<String> newEntries = Sets.newHashSet("user::rwx", "group::rwx", "other::rwx"); mFileSystemMaster.setAcl(NESTED_URI, SetAclAction.REPLACE, newEntries.stream().map(AclEntry::fromCliString).collect(Collectors.toList()), SetAclContext.defaults(SetAclPOptions.newBuilder().setRecursive(true))); entries = Sets.newHashSet(mFileSystemMaster.getFileInfo(NESTED_FILE_URI, GET_STATUS_CONTEXT) .convertAclToStringEntries()); assertEquals(newEntries, entries); } }
/** * Changes the permissions of directory or file with the path specified in args. * * @param path The {@link AlluxioURI} path as the input of the command * @param modeStr The new permission to be updated to the file or directory * @param recursive Whether change the permission recursively */ private void chmod(AlluxioURI path, String modeStr, boolean recursive) throws AlluxioException, IOException { Mode mode = ModeParser.parse(modeStr); SetAttributePOptions options = SetAttributePOptions.newBuilder().setMode(mode.toProto()).setRecursive(recursive).build(); mFileSystem.setAttribute(path, options); System.out .println("Changed permission of " + path + " to " + Integer.toOctalString(mode.toShort())); }
@Test public void deleteDirRecursiveWithPermissions() throws Exception { // userA has permissions to delete directory and nested file createFileWithSingleBlock(NESTED_FILE_URI); mFileSystemMaster.setAttribute(NESTED_URI, SetAttributeContext .defaults(SetAttributePOptions.newBuilder().setMode(new Mode((short) 0777).toProto()))); mFileSystemMaster.setAttribute(NESTED_FILE_URI, SetAttributeContext .defaults(SetAttributePOptions.newBuilder().setMode(new Mode((short) 0777).toProto()))); try (AuthenticatedClientUserResource userA = new AuthenticatedClientUserResource("userA", ServerConfiguration.global())) { mFileSystemMaster.delete(NESTED_URI, DeleteContext.defaults(DeletePOptions.newBuilder().setRecursive(true))); } assertEquals(IdUtils.INVALID_FILE_ID, mFileSystemMaster.getFileId(NESTED_URI)); assertEquals(IdUtils.INVALID_FILE_ID, mFileSystemMaster.getFileId(NESTED_FILE_URI)); }