static HdfsFileStatus setAcl( FSDirectory fsd, final String srcArg, List<AclEntry> aclSpec) throws IOException { String src = srcArg; checkAclsConfigFlag(fsd); byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src); FSPermissionChecker pc = fsd.getPermissionChecker(); src = fsd.resolvePath(pc, src, pathComponents); INodesInPath iip; fsd.writeLock(); try { iip = fsd.getINodesInPath4Write(src); fsd.checkOwner(pc, iip); List<AclEntry> newAcl = unprotectedSetAcl(fsd, src, aclSpec, false); fsd.getEditLog().logSetAcl(src, newAcl); } finally { fsd.writeUnlock(); } return fsd.getAuditFileInfo(iip); }
@Test public void testFilterDefaultAclEntries() throws AclException { List<AclEntry> existing = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, USER, "bruce", READ_WRITE)) .add(aclEntry(ACCESS, GROUP, READ_EXECUTE)) .add(aclEntry(ACCESS, GROUP, "sales", READ_EXECUTE)) .add(aclEntry(ACCESS, MASK, ALL)) .add(aclEntry(ACCESS, OTHER, NONE)) .add(aclEntry(DEFAULT, USER, ALL)) .add(aclEntry(DEFAULT, USER, "bruce", READ_WRITE)) .add(aclEntry(DEFAULT, GROUP, READ)) .add(aclEntry(DEFAULT, GROUP, "sales", READ_EXECUTE)) .add(aclEntry(DEFAULT, MASK, READ_WRITE)) .add(aclEntry(DEFAULT, OTHER, READ_EXECUTE)) .build(); List<AclEntry> expected = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, USER, "bruce", READ_WRITE)) .add(aclEntry(ACCESS, GROUP, READ_EXECUTE)) .add(aclEntry(ACCESS, GROUP, "sales", READ_EXECUTE)) .add(aclEntry(ACCESS, MASK, ALL)) .add(aclEntry(ACCESS, OTHER, NONE)) .build(); assertEquals(expected, filterDefaultAclEntries(existing)); }
private List<AclEntry> getAclEntryList(String path) throws IOException { long id = lookup(path); FsImageProto.INodeSection.INode inode = fromINodeId(id); switch (inode.getType()) { case FILE: { FsImageProto.INodeSection.INodeFile f = inode.getFile(); return FSImageFormatPBINode.Loader.loadAclEntries( f.getAcl(), stringTable); } case DIRECTORY: { FsImageProto.INodeSection.INodeDirectory d = inode.getDirectory(); return FSImageFormatPBINode.Loader.loadAclEntries( d.getAcl(), stringTable); } default: { return new ArrayList<AclEntry>(); } } }
@Test(expected=AclException.class) public void testReplaceAclEntriesResultTooLarge() throws AclException { List<AclEntry> existing = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, OTHER, NONE)) .build(); List<AclEntry> aclSpec = Lists.newArrayListWithCapacity(32); aclSpec.add(aclEntry(ACCESS, USER, ALL)); for (int i = 1; i <= 29; ++i) { aclSpec.add(aclEntry(ACCESS, USER, "user" + i, READ)); } aclSpec.add(aclEntry(ACCESS, GROUP, READ)); aclSpec.add(aclEntry(ACCESS, OTHER, NONE)); // The ACL spec now has 32 entries. Automatic mask calculation will push it // over the limit to 33. replaceAclEntries(existing, aclSpec); }
@Test public void testSetPermissionOnlyDefault() throws IOException { FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(ACCESS, USER, ALL), aclEntry(ACCESS, GROUP, READ_EXECUTE), aclEntry(ACCESS, OTHER, NONE), aclEntry(DEFAULT, USER, "foo", ALL)); fs.setAcl(path, aclSpec); fs.setPermission(path, FsPermission.createImmutable((short)0700)); AclStatus s = fs.getAclStatus(path); AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { aclEntry(DEFAULT, USER, ALL), aclEntry(DEFAULT, USER, "foo", ALL), aclEntry(DEFAULT, GROUP, READ_EXECUTE), aclEntry(DEFAULT, MASK, ALL), aclEntry(DEFAULT, OTHER, NONE) }, returned); assertPermission((short)010700); assertAclFeature(true); }
private static void write(List<AclEntry> aclEntries, DataOutputStream out) throws IOException { if (aclEntries == null) { out.writeInt(0); return; } out.writeInt(aclEntries.size()); for (AclEntry e : aclEntries) { boolean hasName = e.getName() != null; int v = (e.getScope().ordinal() << ACL_EDITLOG_ENTRY_SCOPE_OFFSET) | (e.getType().ordinal() << ACL_EDITLOG_ENTRY_TYPE_OFFSET) | e.getPermission().ordinal(); if (hasName) { v |= 1 << ACL_EDITLOG_ENTRY_HAS_NAME_OFFSET; } out.write(v); if (hasName) { FSImageSerialization.writeString(e.getName(), out); } } }
@Test public void testRemoveAclEntries() throws IOException { FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(ACCESS, USER, ALL), aclEntry(ACCESS, USER, "foo", ALL), aclEntry(ACCESS, GROUP, READ_EXECUTE), aclEntry(ACCESS, OTHER, NONE), aclEntry(DEFAULT, USER, "foo", ALL)); fs.setAcl(path, aclSpec); aclSpec = Lists.newArrayList( aclEntry(ACCESS, USER, "foo"), aclEntry(DEFAULT, USER, "foo")); fs.removeAclEntries(path, aclSpec); AclStatus s = fs.getAclStatus(path); AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { aclEntry(ACCESS, GROUP, READ_EXECUTE), aclEntry(DEFAULT, USER, ALL), aclEntry(DEFAULT, GROUP, READ_EXECUTE), aclEntry(DEFAULT, MASK, READ_EXECUTE), aclEntry(DEFAULT, OTHER, NONE) }, returned); assertPermission((short)010750); assertAclFeature(true); }
@Test public void testToAclStatus() throws IOException { String jsonString = "{\"AclStatus\":{\"entries\":[\"user::rwx\",\"user:user1:rw-\",\"group::rw-\",\"other::r-x\"],\"group\":\"supergroup\",\"owner\":\"testuser\",\"stickyBit\":false}}"; ObjectReader reader = new ObjectMapper().reader(Map.class); Map<?, ?> json = reader.readValue(jsonString); List<AclEntry> aclSpec = Lists.newArrayList(aclEntry(ACCESS, USER, ALL), aclEntry(ACCESS, USER, "user1", READ_WRITE), aclEntry(ACCESS, GROUP, READ_WRITE), aclEntry(ACCESS, OTHER, READ_EXECUTE)); AclStatus.Builder aclStatusBuilder = new AclStatus.Builder(); aclStatusBuilder.owner("testuser"); aclStatusBuilder.group("supergroup"); aclStatusBuilder.addEntries(aclSpec); aclStatusBuilder.stickyBit(false); Assert.assertEquals("Should be equal", aclStatusBuilder.build(), JsonUtil.toAclStatus(json)); }
@Test public void testMergeAclEntriesAutomaticDefaultOther() throws AclException { List<AclEntry> existing = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, OTHER, NONE)) .build(); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(DEFAULT, USER, READ_EXECUTE), aclEntry(DEFAULT, GROUP, READ_EXECUTE)); List<AclEntry> expected = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, OTHER, NONE)) .add(aclEntry(DEFAULT, USER, READ_EXECUTE)) .add(aclEntry(DEFAULT, GROUP, READ_EXECUTE)) .add(aclEntry(DEFAULT, OTHER, NONE)) .build(); assertEquals(expected, mergeAclEntries(existing, aclSpec)); }
@Test public void testReplaceAclEntriesAccessMaskCalculated() throws AclException { List<AclEntry> existing = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, OTHER, READ)) .build(); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(ACCESS, USER, ALL), aclEntry(ACCESS, USER, "bruce", READ), aclEntry(ACCESS, USER, "diana", READ_WRITE), aclEntry(ACCESS, GROUP, READ), aclEntry(ACCESS, OTHER, READ)); List<AclEntry> expected = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, USER, "bruce", READ)) .add(aclEntry(ACCESS, USER, "diana", READ_WRITE)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, MASK, READ_WRITE)) .add(aclEntry(ACCESS, OTHER, READ)) .build(); assertEquals(expected, replaceAclEntries(existing, aclSpec)); }
@Test public void testSetAclStickyBit() throws IOException { FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)01750)); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(ACCESS, USER, ALL), aclEntry(ACCESS, USER, "foo", ALL), aclEntry(ACCESS, GROUP, READ_EXECUTE), aclEntry(ACCESS, OTHER, NONE), aclEntry(DEFAULT, USER, "foo", ALL)); fs.setAcl(path, aclSpec); AclStatus s = fs.getAclStatus(path); AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { aclEntry(ACCESS, USER, "foo", ALL), aclEntry(ACCESS, GROUP, READ_EXECUTE), aclEntry(DEFAULT, USER, ALL), aclEntry(DEFAULT, USER, "foo", ALL), aclEntry(DEFAULT, GROUP, READ_EXECUTE), aclEntry(DEFAULT, MASK, ALL), aclEntry(DEFAULT, OTHER, NONE) }, returned); assertPermission((short)011770); assertAclFeature(true); }
@Test public void testMergeAclEntries() throws AclException { List<AclEntry> existing = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, GROUP, READ_EXECUTE)) .add(aclEntry(ACCESS, OTHER, NONE)) .build(); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(ACCESS, USER, "bruce", ALL)); List<AclEntry> expected = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, USER, "bruce", ALL)) .add(aclEntry(ACCESS, GROUP, READ_EXECUTE)) .add(aclEntry(ACCESS, MASK, ALL)) .add(aclEntry(ACCESS, OTHER, NONE)) .build(); assertEquals(expected, mergeAclEntries(existing, aclSpec)); }
@Test public void testRemoveAclEntriesOnlyAccess() throws IOException { fs.create(path).close(); fs.setPermission(path, FsPermission.createImmutable((short)0640)); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(ACCESS, USER, ALL), aclEntry(ACCESS, USER, "foo", ALL), aclEntry(ACCESS, USER, "bar", READ_WRITE), aclEntry(ACCESS, GROUP, READ_WRITE), aclEntry(ACCESS, OTHER, NONE)); fs.setAcl(path, aclSpec); aclSpec = Lists.newArrayList( aclEntry(ACCESS, USER, "foo")); fs.removeAclEntries(path, aclSpec); AclStatus s = fs.getAclStatus(path); AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { aclEntry(ACCESS, USER, "bar", READ_WRITE), aclEntry(ACCESS, GROUP, READ_WRITE) }, returned); assertPermission((short)010760); assertAclFeature(true); }
@Test public void testReplaceAclEntriesOnlyDefaults() throws AclException { List<AclEntry> existing = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, OTHER, NONE)) .build(); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(DEFAULT, USER, "bruce", READ)); List<AclEntry> expected = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, OTHER, NONE)) .add(aclEntry(DEFAULT, USER, ALL)) .add(aclEntry(DEFAULT, USER, "bruce", READ)) .add(aclEntry(DEFAULT, GROUP, READ)) .add(aclEntry(DEFAULT, MASK, READ)) .add(aclEntry(DEFAULT, OTHER, NONE)) .build(); assertEquals(expected, replaceAclEntries(existing, aclSpec)); }
@Test(expected=AclException.class) public void testFilterAclEntriesByAclSpecRemoveDefaultMaskRequired() throws AclException { List<AclEntry> existing = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, OTHER, NONE)) .add(aclEntry(DEFAULT, USER, ALL)) .add(aclEntry(DEFAULT, USER, "bruce", READ)) .add(aclEntry(DEFAULT, GROUP, READ)) .add(aclEntry(DEFAULT, MASK, ALL)) .add(aclEntry(DEFAULT, OTHER, NONE)) .build(); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(DEFAULT, MASK)); filterAclEntriesByAclSpec(existing, aclSpec); }
private static void doSnapshotRootChangeAssertions(Path path, Path snapshotPath) throws Exception { AclStatus s = hdfs.getAclStatus(path); AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { aclEntry(ACCESS, USER, "diana", READ_EXECUTE), aclEntry(ACCESS, GROUP, NONE) }, returned); assertPermission((short)010550, path); s = hdfs.getAclStatus(snapshotPath); returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { aclEntry(ACCESS, USER, "bruce", READ_EXECUTE), aclEntry(ACCESS, GROUP, NONE) }, returned); assertPermission((short)010750, snapshotPath); assertDirPermissionDenied(fsAsBruce, BRUCE, path); assertDirPermissionGranted(fsAsDiana, DIANA, path); assertDirPermissionGranted(fsAsBruce, BRUCE, snapshotPath); assertDirPermissionDenied(fsAsDiana, DIANA, snapshotPath); }
@Test public void testToJsonFromAclStatus() { String jsonString = "{\"AclStatus\":{\"entries\":[\"user:user1:rwx\",\"group::rw-\"],\"group\":\"supergroup\",\"owner\":\"testuser\",\"stickyBit\":false}}"; AclStatus.Builder aclStatusBuilder = new AclStatus.Builder(); aclStatusBuilder.owner("testuser"); aclStatusBuilder.group("supergroup"); aclStatusBuilder.stickyBit(false); List<AclEntry> aclSpec = Lists.newArrayList(aclEntry(ACCESS, USER,"user1", ALL), aclEntry(ACCESS, GROUP, READ_WRITE)); aclStatusBuilder.addEntries(aclSpec); Assert.assertEquals(jsonString, JsonUtil.toJsonString(aclStatusBuilder.build())); }
@Test public void testDefaultAclNewFile() throws Exception { FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(DEFAULT, USER, "foo", ALL)); fs.setAcl(path, aclSpec); Path filePath = new Path(path, "file1"); fs.create(filePath).close(); AclStatus s = fs.getAclStatus(filePath); AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { aclEntry(ACCESS, USER, "foo", ALL), aclEntry(ACCESS, GROUP, READ_EXECUTE) }, returned); assertPermission(filePath, (short)010640); assertAclFeature(filePath, true); }
@Test public void testRemoveDefaultAcl() throws Exception { FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(ACCESS, USER, ALL), aclEntry(ACCESS, USER, "foo", ALL), aclEntry(ACCESS, GROUP, READ_EXECUTE), aclEntry(ACCESS, OTHER, NONE), aclEntry(DEFAULT, USER, "foo", ALL)); fs.setAcl(path, aclSpec); fs.removeDefaultAcl(path); AclStatus s = fs.getAclStatus(path); AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { aclEntry(ACCESS, USER, "foo", ALL), aclEntry(ACCESS, GROUP, READ_EXECUTE) }, returned); assertPermission((short)010770); assertAclFeature(true); // restart of the cluster restartCluster(); s = fs.getAclStatus(path); AclEntry[] afterRestart = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(returned, afterRestart); }
@Test public void testRemoveDefaultAclOnlyAccess() throws Exception { fs.create(path).close(); fs.setPermission(path, FsPermission.createImmutable((short)0640)); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(ACCESS, USER, ALL), aclEntry(ACCESS, USER, "foo", ALL), aclEntry(ACCESS, GROUP, READ_EXECUTE), aclEntry(ACCESS, OTHER, NONE)); fs.setAcl(path, aclSpec); fs.removeDefaultAcl(path); AclStatus s = fs.getAclStatus(path); AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { aclEntry(ACCESS, USER, "foo", ALL), aclEntry(ACCESS, GROUP, READ_EXECUTE) }, returned); assertPermission((short)010770); assertAclFeature(true); // restart of the cluster restartCluster(); s = fs.getAclStatus(path); AclEntry[] afterRestart = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(returned, afterRestart); }
public static ImmutableList<AclEntry> loadAclEntries( AclFeatureProto proto, final String[] stringTable) { ImmutableList.Builder<AclEntry> b = ImmutableList.builder(); for (int v : proto.getEntriesList()) { int p = v & ACL_ENTRY_PERM_MASK; int t = (v >> ACL_ENTRY_TYPE_OFFSET) & ACL_ENTRY_TYPE_MASK; int s = (v >> ACL_ENTRY_SCOPE_OFFSET) & ACL_ENTRY_SCOPE_MASK; int nid = (v >> ACL_ENTRY_NAME_OFFSET) & ACL_ENTRY_NAME_MASK; String name = stringTable[nid]; b.add(new AclEntry.Builder().setName(name) .setPermission(FSACTION_VALUES[p]) .setScope(ACL_ENTRY_SCOPE_VALUES[s]) .setType(ACL_ENTRY_TYPE_VALUES[t]).build()); } return b.build(); }
@Test public void testAclEntryProto() { // All fields populated. AclEntry e1 = new AclEntry.Builder().setName("test") .setPermission(FsAction.READ_EXECUTE).setScope(AclEntryScope.DEFAULT) .setType(AclEntryType.OTHER).build(); // No name. AclEntry e2 = new AclEntry.Builder().setScope(AclEntryScope.ACCESS) .setType(AclEntryType.USER).setPermission(FsAction.ALL).build(); // No permission, which will default to the 0'th enum element. AclEntry e3 = new AclEntry.Builder().setScope(AclEntryScope.ACCESS) .setType(AclEntryType.USER).setName("test").build(); AclEntry[] expected = new AclEntry[] { e1, e2, new AclEntry.Builder() .setScope(e3.getScope()) .setType(e3.getType()) .setName(e3.getName()) .setPermission(FsAction.NONE) .build() }; AclEntry[] actual = Lists.newArrayList( PBHelper.convertAclEntry(PBHelper.convertAclEntryProto(Lists .newArrayList(e1, e2, e3)))).toArray(new AclEntry[0]); Assert.assertArrayEquals(expected, actual); }
/** * Prints a single extended ACL entry. If the mask restricts the * permissions of the entry, then also prints the restricted version as the * effective permissions. The mask applies to all named entries and also * the unnamed group entry. * @param aclStatus AclStatus for the path * @param fsPerm FsPermission for the path * @param entry AclEntry extended ACL entry to print */ private void printExtendedAclEntry(AclStatus aclStatus, FsPermission fsPerm, AclEntry entry) { if (entry.getName() != null || entry.getType() == AclEntryType.GROUP) { FsAction entryPerm = entry.getPermission(); FsAction effectivePerm = aclStatus .getEffectivePermission(entry, fsPerm); if (entryPerm != effectivePerm) { out.println(String.format("%s\t#effective:%s", entry, effectivePerm.SYMBOL)); } else { out.println(entry); } } else { out.println(entry); } }
@Test public void testModifyAclEntriesMinimalDefault() throws IOException { FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(DEFAULT, USER, ALL), aclEntry(DEFAULT, GROUP, READ_EXECUTE), aclEntry(DEFAULT, OTHER, NONE)); fs.modifyAclEntries(path, aclSpec); AclStatus s = fs.getAclStatus(path); AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { aclEntry(DEFAULT, USER, ALL), aclEntry(DEFAULT, GROUP, READ_EXECUTE), aclEntry(DEFAULT, OTHER, NONE) }, returned); assertPermission((short)010750); assertAclFeature(true); }
@Test(expected=FileNotFoundException.class) public void testModifyAclEntriesPathNotFound() throws IOException { // Path has not been created. List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(ACCESS, USER, ALL), aclEntry(ACCESS, USER, "foo", ALL), aclEntry(ACCESS, GROUP, READ_EXECUTE), aclEntry(ACCESS, OTHER, NONE)); fs.modifyAclEntries(path, aclSpec); }
@Test public void testMergeAclEntriesAccessMaskPreserved() throws AclException { List<AclEntry> existing = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, USER, "bruce", READ)) .add(aclEntry(ACCESS, USER, "diana", READ_WRITE)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, MASK, READ)) .add(aclEntry(ACCESS, OTHER, READ)) .add(aclEntry(DEFAULT, USER, ALL)) .add(aclEntry(DEFAULT, USER, "bruce", READ)) .add(aclEntry(DEFAULT, USER, "diana", READ_WRITE)) .add(aclEntry(DEFAULT, GROUP, READ)) .add(aclEntry(DEFAULT, MASK, READ_WRITE)) .add(aclEntry(DEFAULT, OTHER, NONE)) .build(); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(DEFAULT, USER, "diana", READ_EXECUTE)); List<AclEntry> expected = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, USER, "bruce", READ)) .add(aclEntry(ACCESS, USER, "diana", READ_WRITE)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, MASK, READ)) .add(aclEntry(ACCESS, OTHER, READ)) .add(aclEntry(DEFAULT, USER, ALL)) .add(aclEntry(DEFAULT, USER, "bruce", READ)) .add(aclEntry(DEFAULT, USER, "diana", READ_EXECUTE)) .add(aclEntry(DEFAULT, GROUP, READ)) .add(aclEntry(DEFAULT, MASK, READ_EXECUTE)) .add(aclEntry(DEFAULT, OTHER, NONE)) .build(); assertEquals(expected, mergeAclEntries(existing, aclSpec)); }
/** * Creates a new ScopedAclEntries from the given list. It is assumed that the * list is already sorted such that all access entries precede all default * entries. * * @param aclEntries List<AclEntry> to separate */ public ScopedAclEntries(List<AclEntry> aclEntries) { int pivot = calculatePivotOnDefaultEntries(aclEntries); if (pivot != PIVOT_NOT_FOUND) { accessEntries = pivot != 0 ? aclEntries.subList(0, pivot) : Collections.<AclEntry>emptyList(); defaultEntries = aclEntries.subList(pivot, aclEntries.size()); } else { accessEntries = aclEntries; defaultEntries = Collections.emptyList(); } }
@Test public void testFilterAclEntriesByAclSpecAccessMaskPreserved() throws AclException { List<AclEntry> existing = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, USER, "bruce", READ)) .add(aclEntry(ACCESS, USER, "diana", READ_WRITE)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, MASK, READ)) .add(aclEntry(ACCESS, OTHER, READ)) .add(aclEntry(DEFAULT, USER, ALL)) .add(aclEntry(DEFAULT, USER, "bruce", READ)) .add(aclEntry(DEFAULT, USER, "diana", READ_WRITE)) .add(aclEntry(DEFAULT, GROUP, READ)) .add(aclEntry(DEFAULT, MASK, READ_WRITE)) .add(aclEntry(DEFAULT, OTHER, NONE)) .build(); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(DEFAULT, USER, "diana")); List<AclEntry> expected = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, USER, "bruce", READ)) .add(aclEntry(ACCESS, USER, "diana", READ_WRITE)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, MASK, READ)) .add(aclEntry(ACCESS, OTHER, READ)) .add(aclEntry(DEFAULT, USER, ALL)) .add(aclEntry(DEFAULT, USER, "bruce", READ)) .add(aclEntry(DEFAULT, GROUP, READ)) .add(aclEntry(DEFAULT, MASK, READ)) .add(aclEntry(DEFAULT, OTHER, NONE)) .build(); assertEquals(expected, filterAclEntriesByAclSpec(existing, aclSpec)); }
public static List<AclEntryProto> convertAclEntryProto( List<AclEntry> aclSpec) { ArrayList<AclEntryProto> r = Lists.newArrayListWithCapacity(aclSpec.size()); for (AclEntry e : aclSpec) { AclEntryProto.Builder builder = AclEntryProto.newBuilder(); builder.setType(convert(e.getType())); builder.setScope(convert(e.getScope())); builder.setPermissions(convert(e.getPermission())); if (e.getName() != null) { builder.setName(e.getName()); } r.add(builder.build()); } return r; }
@Test public void testRemoveAclMinimalAcl() throws IOException { fs.create(path).close(); fs.setPermission(path, FsPermission.createImmutable((short)0640)); fs.removeAcl(path); AclStatus s = fs.getAclStatus(path); AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { }, returned); assertPermission((short)0640); assertAclFeature(false); }
@Override public void removeAclEntries(Path path, List<AclEntry> aclSpec) throws IOException { InodeTree.ResolveResult<AbstractFileSystem> res = fsState.resolve(getUriPath(path), true); res.targetFileSystem.removeAclEntries(res.remainingPath, aclSpec); }
@Override public void modifyAclEntries(Path path, List<AclEntry> aclSpec) throws IOException { try { underlyingFs.modifyAclEntries(path, aclSpec); } catch(FSError e) { throw propagateFSError(e); } }
@Test public void testMultipleAclSpecParsingWithoutPermissions() throws Exception { List<AclEntry> parsedList = AclEntry.parseAclSpec( "user::,user:user1:,group::,group:group1:,mask::,other::," + "default:user:user1::,default:mask::", false); AclEntry owner = new AclEntry.Builder().setType(AclEntryType.USER).build(); AclEntry namedUser = new AclEntry.Builder().setType(AclEntryType.USER) .setName("user1").build(); AclEntry group = new AclEntry.Builder().setType(AclEntryType.GROUP).build(); AclEntry namedGroup = new AclEntry.Builder().setType(AclEntryType.GROUP) .setName("group1").build(); AclEntry mask = new AclEntry.Builder().setType(AclEntryType.MASK).build(); AclEntry other = new AclEntry.Builder().setType(AclEntryType.OTHER).build(); AclEntry defaultUser = new AclEntry.Builder() .setScope(AclEntryScope.DEFAULT).setType(AclEntryType.USER) .setName("user1").build(); AclEntry defaultMask = new AclEntry.Builder() .setScope(AclEntryScope.DEFAULT).setType(AclEntryType.MASK).build(); List<AclEntry> expectedList = new ArrayList<AclEntry>(); expectedList.add(owner); expectedList.add(namedUser); expectedList.add(group); expectedList.add(namedGroup); expectedList.add(mask); expectedList.add(other); expectedList.add(defaultUser); expectedList.add(defaultMask); assertEquals("Parsed Acl not correct", expectedList, parsedList); }
@Override public void modifyAclEntries(Path path, List<AclEntry> aclSpec) throws IOException { InodeTree.ResolveResult<FileSystem> res = fsState.resolve(getUriPath(path), true); res.targetFileSystem.modifyAclEntries(res.remainingPath, aclSpec); }
@Test public void testMergeAclEntriesDefaultMaskPreserved() throws AclException { List<AclEntry> existing = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, OTHER, READ)) .add(aclEntry(DEFAULT, USER, ALL)) .add(aclEntry(DEFAULT, USER, "diana", ALL)) .add(aclEntry(DEFAULT, GROUP, READ)) .add(aclEntry(DEFAULT, MASK, READ)) .add(aclEntry(DEFAULT, OTHER, NONE)) .build(); List<AclEntry> aclSpec = Lists.newArrayList( aclEntry(ACCESS, USER, "diana", FsAction.READ_EXECUTE)); List<AclEntry> expected = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, USER, "diana", READ_EXECUTE)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, MASK, READ_EXECUTE)) .add(aclEntry(ACCESS, OTHER, READ)) .add(aclEntry(DEFAULT, USER, ALL)) .add(aclEntry(DEFAULT, USER, "diana", ALL)) .add(aclEntry(DEFAULT, GROUP, READ)) .add(aclEntry(DEFAULT, MASK, READ)) .add(aclEntry(DEFAULT, OTHER, NONE)) .build(); assertEquals(expected, mergeAclEntries(existing, aclSpec)); }
@Override public void modifyAclEntries(Path path, List<AclEntry> aclSpec) throws IOException { InodeTree.ResolveResult<AbstractFileSystem> res = fsState.resolve(getUriPath(path), true); res.targetFileSystem.modifyAclEntries(res.remainingPath, aclSpec); }
@Test(expected=AclException.class) public void testReplaceAclEntriesInputTooLarge() throws AclException { List<AclEntry> existing = new ImmutableList.Builder<AclEntry>() .add(aclEntry(ACCESS, USER, ALL)) .add(aclEntry(ACCESS, GROUP, READ)) .add(aclEntry(ACCESS, OTHER, NONE)) .build(); replaceAclEntries(existing, ACL_SPEC_TOO_LARGE); }
/** * Create a new AclEntry with scope, type and permission (no name). * * @param scope AclEntryScope scope of the ACL entry * @param type AclEntryType ACL entry type * @param permission FsAction set of permissions in the ACL entry * @return AclEntry new AclEntry */ public static AclEntry aclEntry(AclEntryScope scope, AclEntryType type, FsAction permission) { return new AclEntry.Builder() .setScope(scope) .setType(type) .setPermission(permission) .build(); }
@Override public void removeAclEntries(Path path, List<AclEntry> aclSpec) throws IOException { try { underlyingFs.removeAclEntries(path, aclSpec); } catch(FSError e) { throw propagateFSError(e); } }
@Override public int compare(AclEntry entry1, AclEntry entry2) { return ComparisonChain.start() .compare(entry1.getScope(), entry2.getScope(), Ordering.explicit(ACCESS, DEFAULT)) .compare(entry1.getType(), entry2.getType(), Ordering.explicit(USER, GROUP, MASK, OTHER)) .compare(entry1.getName(), entry2.getName(), Ordering.natural().nullsFirst()) .result(); }