/// <exception cref="System.IO.IOException"/> private static void UnprotectedRemoveAcl(FSDirectory fsd, INodesInPath iip) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); INode inode = FSDirectory.ResolveLastINode(iip); int snapshotId = iip.GetLatestSnapshotId(); AclFeature f = inode.GetAclFeature(); if (f == null) { return; } FsPermission perm = inode.GetFsPermission(); IList <AclEntry> featureEntries = AclStorage.GetEntriesFromAclFeature(f); if (featureEntries[0].GetScope() == AclEntryScope.Access) { // Restore group permissions from the feature's entry to permission // bits, overwriting the mask, which is not part of a minimal ACL. AclEntry groupEntryKey = new AclEntry.Builder().SetScope(AclEntryScope.Access).SetType (AclEntryType.Group).Build(); int groupEntryIndex = Sharpen.Collections.BinarySearch(featureEntries, groupEntryKey , AclTransformation.AclEntryComparator); System.Diagnostics.Debug.Assert(groupEntryIndex >= 0); FsAction groupPerm = featureEntries[groupEntryIndex].GetPermission(); FsPermission newPerm = new FsPermission(perm.GetUserAction(), groupPerm, perm.GetOtherAction (), perm.GetStickyBit()); inode.SetPermission(newPerm, snapshotId); } inode.RemoveAclFeature(snapshotId); }
public virtual void TestRootACLAfterLoadingFsImage() { DistributedFileSystem fs = cluster.GetFileSystem(); Path rootdir = new Path("/"); AclEntry e1 = new AclEntry.Builder().SetName("foo").SetPermission(FsAction.All).SetScope (AclEntryScope.Access).SetType(AclEntryType.Group).Build(); AclEntry e2 = new AclEntry.Builder().SetName("bar").SetPermission(FsAction.Read). SetScope(AclEntryScope.Access).SetType(AclEntryType.Group).Build(); fs.ModifyAclEntries(rootdir, Lists.NewArrayList(e1, e2)); AclStatus s = cluster.GetNamesystem().GetAclStatus(rootdir.ToString()); AclEntry[] returned = Sharpen.Collections.ToArray(Lists.NewArrayList(s.GetEntries ()), new AclEntry[0]); Assert.AssertArrayEquals(new AclEntry[] { AclTestHelpers.AclEntry(AclEntryScope.Access , AclEntryType.Group, FsAction.ReadExecute), AclTestHelpers.AclEntry(AclEntryScope .Access, AclEntryType.Group, "bar", FsAction.Read), AclTestHelpers.AclEntry(AclEntryScope .Access, AclEntryType.Group, "foo", FsAction.All) }, returned); // restart - hence save and load from fsimage Restart(fs, true); s = cluster.GetNamesystem().GetAclStatus(rootdir.ToString()); returned = Sharpen.Collections.ToArray(Lists.NewArrayList(s.GetEntries()), new AclEntry [0]); Assert.AssertArrayEquals(new AclEntry[] { AclTestHelpers.AclEntry(AclEntryScope.Access , AclEntryType.Group, FsAction.ReadExecute), AclTestHelpers.AclEntry(AclEntryScope .Access, AclEntryType.Group, "bar", FsAction.Read), AclTestHelpers.AclEntry(AclEntryScope .Access, AclEntryType.Group, "foo", FsAction.All) }, returned); }
/// <summary> /// Adds unspecified default entries by copying permissions from the /// corresponding access entries. /// </summary> /// <param name="aclBuilder">ArrayList<AclEntry> containing entries to build</param> private static void CopyDefaultsIfNeeded(IList <AclEntry> aclBuilder) { aclBuilder.Sort(AclEntryComparator); ScopedAclEntries scopedEntries = new ScopedAclEntries(aclBuilder); if (!scopedEntries.GetDefaultEntries().IsEmpty()) { IList <AclEntry> accessEntries = scopedEntries.GetAccessEntries(); IList <AclEntry> defaultEntries = scopedEntries.GetDefaultEntries(); IList <AclEntry> copiedEntries = Lists.NewArrayListWithCapacity(3); foreach (AclEntryType type in EnumSet.Of(AclEntryType.User, AclEntryType.Group, AclEntryType .Other)) { AclEntry defaultEntryKey = new AclEntry.Builder().SetScope(AclEntryScope.Default) .SetType(type).Build(); int defaultEntryIndex = Sharpen.Collections.BinarySearch(defaultEntries, defaultEntryKey , AclEntryComparator); if (defaultEntryIndex < 0) { AclEntry accessEntryKey = new AclEntry.Builder().SetScope(AclEntryScope.Access).SetType (type).Build(); int accessEntryIndex = Sharpen.Collections.BinarySearch(accessEntries, accessEntryKey , AclEntryComparator); if (accessEntryIndex >= 0) { copiedEntries.AddItem(new AclEntry.Builder().SetScope(AclEntryScope.Default).SetType (type).SetPermission(accessEntries[accessEntryIndex].GetPermission()).Build()); } } } // Add all copied entries when done to prevent potential issues with binary // search on a modified aclBulider during the main loop. Sharpen.Collections.AddAll(aclBuilder, copiedEntries); } }
public virtual void TestMultipleAclSpecParsingWithoutPermissions() { IList <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(); IList <AclEntry> expectedList = new AList <AclEntry>(); expectedList.AddItem(owner); expectedList.AddItem(namedUser); expectedList.AddItem(group); expectedList.AddItem(namedGroup); expectedList.AddItem(mask); expectedList.AddItem(other); expectedList.AddItem(defaultUser); expectedList.AddItem(defaultMask); Assert.Equal("Parsed Acl not correct", expectedList, parsedList ); }
public virtual void TestAclStatusProto() { AclEntry e = new AclEntry.Builder().SetName("test").SetPermission(FsAction.ReadExecute ).SetScope(AclEntryScope.Default).SetType(AclEntryType.Other).Build(); AclStatus s = new AclStatus.Builder().Owner("foo").Group("bar").AddEntry(e).Build (); NUnit.Framework.Assert.AreEqual(s, PBHelper.Convert(PBHelper.Convert(s))); }
/// <summary> /// Builds the final list of ACL entries to return by trimming, sorting and /// validating the ACL entries that have been added. /// </summary> /// <param name="aclBuilder">ArrayList<AclEntry> containing entries to build</param> /// <returns>List<AclEntry> unmodifiable, sorted list of ACL entries</returns> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.AclException">if validation fails /// </exception> private static IList <AclEntry> BuildAndValidateAcl(AList <AclEntry> aclBuilder) { if (aclBuilder.Count > MaxEntries) { throw new AclException("Invalid ACL: ACL has " + aclBuilder.Count + " entries, which exceeds maximum of " + MaxEntries + "."); } aclBuilder.TrimToSize(); aclBuilder.Sort(AclEntryComparator); // Full iteration to check for duplicates and invalid named entries. AclEntry prevEntry = null; foreach (AclEntry entry in aclBuilder) { if (prevEntry != null && AclEntryComparator.Compare(prevEntry, entry) == 0) { throw new AclException("Invalid ACL: multiple entries with same scope, type and name." ); } if (entry.GetName() != null && (entry.GetType() == AclEntryType.Mask || entry.GetType () == AclEntryType.Other)) { throw new AclException("Invalid ACL: this entry type must not have a name: " + entry + "."); } prevEntry = entry; } // Search for the required base access entries. If there is a default ACL, // then do the same check on the default entries. ScopedAclEntries scopedEntries = new ScopedAclEntries(aclBuilder); foreach (AclEntryType type in EnumSet.Of(AclEntryType.User, AclEntryType.Group, AclEntryType .Other)) { AclEntry accessEntryKey = new AclEntry.Builder().SetScope(AclEntryScope.Access).SetType (type).Build(); if (Sharpen.Collections.BinarySearch(scopedEntries.GetAccessEntries(), accessEntryKey , AclEntryComparator) < 0) { throw new AclException("Invalid ACL: the user, group and other entries are required." ); } if (!scopedEntries.GetDefaultEntries().IsEmpty()) { AclEntry defaultEntryKey = new AclEntry.Builder().SetScope(AclEntryScope.Default) .SetType(type).Build(); if (Sharpen.Collections.BinarySearch(scopedEntries.GetDefaultEntries(), defaultEntryKey , AclEntryComparator) < 0) { throw new AclException("Invalid default ACL: the user, group and other entries are required." ); } } } return(Sharpen.Collections.UnmodifiableList(aclBuilder)); }
internal static AclEntry ToAclEntry(int aclEntry) { AclEntry.Builder builder = new AclEntry.Builder(); builder.SetScope(GetScope(aclEntry)).SetType(GetType(aclEntry)).SetPermission(GetPermission (aclEntry)); if (GetName(aclEntry) != null) { builder.SetName(GetName(aclEntry)); } return(builder.Build()); }
public override AclFeature GetAclFeature() { AclFeature f; if (useDefault) { f = inode.GetAclFeature(); } else { AclEntry acl = new AclEntry.Builder().SetType(AclEntryType.Group).SetPermission(FsAction .All).SetName("xxx").Build(); f = new AclFeature(AclEntryStatusFormat.ToInt(Lists.NewArrayList(acl))); } return(f); }
public virtual void TestAclEntryProto() { // All fields populated. AclEntry e1 = new AclEntry.Builder().SetName("test").SetPermission(FsAction.ReadExecute ).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 = Sharpen.Collections.ToArray(Lists.NewArrayList(PBHelper.ConvertAclEntry (PBHelper.ConvertAclEntryProto(Lists.NewArrayList(e1, e2, e3)))), new AclEntry[0 ]); Assert.AssertArrayEquals(expected, actual); }
/// <exception cref="System.IO.IOException"/> private void TestAcl(bool persistNamespace) { Path p = new Path("/p"); DistributedFileSystem fs = cluster.GetFileSystem(); fs.Create(p).Close(); fs.Mkdirs(new Path("/23")); AclEntry e = new AclEntry.Builder().SetName("foo").SetPermission(FsAction.ReadExecute ).SetScope(AclEntryScope.Access).SetType(AclEntryType.User).Build(); fs.ModifyAclEntries(p, Lists.NewArrayList(e)); Restart(fs, persistNamespace); AclStatus s = cluster.GetNamesystem().GetAclStatus(p.ToString()); AclEntry[] returned = Sharpen.Collections.ToArray(Lists.NewArrayList(s.GetEntries ()), new AclEntry[0]); Assert.AssertArrayEquals(new AclEntry[] { AclTestHelpers.AclEntry(AclEntryScope.Access , AclEntryType.User, "foo", FsAction.ReadExecute), AclTestHelpers.AclEntry(AclEntryScope .Access, AclEntryType.Group, FsAction.Read) }, returned); fs.RemoveAcl(p); if (persistNamespace) { fs.SetSafeMode(HdfsConstants.SafeModeAction.SafemodeEnter); fs.SaveNamespace(); fs.SetSafeMode(HdfsConstants.SafeModeAction.SafemodeLeave); } cluster.RestartNameNode(); cluster.WaitActive(); s = cluster.GetNamesystem().GetAclStatus(p.ToString()); returned = Sharpen.Collections.ToArray(Lists.NewArrayList(s.GetEntries()), new AclEntry [0]); Assert.AssertArrayEquals(new AclEntry[] { }, returned); fs.ModifyAclEntries(p, Lists.NewArrayList(e)); s = cluster.GetNamesystem().GetAclStatus(p.ToString()); returned = Sharpen.Collections.ToArray(Lists.NewArrayList(s.GetEntries()), new AclEntry [0]); Assert.AssertArrayEquals(new AclEntry[] { AclTestHelpers.AclEntry(AclEntryScope.Access , AclEntryType.User, "foo", FsAction.ReadExecute), AclTestHelpers.AclEntry(AclEntryScope .Access, AclEntryType.Group, FsAction.Read) }, returned); }
public virtual void TestMultipleAclSpecParsing() { IList <AclEntry> parsedList = AclEntry.ParseAclSpec("group::rwx,user:user1:rwx,user:user2:rw-," + "group:group1:rw-,default:group:group1:rw-", true); AclEntry basicAcl = new AclEntry.Builder().SetType(AclEntryType.Group).SetPermission (FsAction.All).Build(); AclEntry user1Acl = new AclEntry.Builder().SetType(AclEntryType.User).SetPermission (FsAction.All).SetName("user1").Build(); AclEntry user2Acl = new AclEntry.Builder().SetType(AclEntryType.User).SetPermission (FsAction.ReadWrite).SetName("user2").Build(); AclEntry group1Acl = new AclEntry.Builder().SetType(AclEntryType.Group).SetPermission (FsAction.ReadWrite).SetName("group1").Build(); AclEntry defaultAcl = new AclEntry.Builder().SetType(AclEntryType.Group).SetPermission (FsAction.ReadWrite).SetName("group1").SetScope(AclEntryScope.Default).Build(); IList <AclEntry> expectedList = new AList <AclEntry>(); expectedList.AddItem(basicAcl); expectedList.AddItem(user1Acl); expectedList.AddItem(user2Acl); expectedList.AddItem(group1Acl); expectedList.AddItem(defaultAcl); Assert.Equal("Parsed Acl not correct", expectedList, parsedList ); }
/// <summary> /// If a default ACL is defined on a parent directory, then copies that default /// ACL to a newly created child file or directory. /// </summary> /// <param name="child">INode newly created child</param> public static void CopyINodeDefaultAcl(INode child) { INodeDirectory parent = child.GetParent(); AclFeature parentAclFeature = parent.GetAclFeature(); if (parentAclFeature == null || !(child.IsFile() || child.IsDirectory())) { return; } // Split parent's entries into access vs. default. IList <AclEntry> featureEntries = GetEntriesFromAclFeature(parent.GetAclFeature()); ScopedAclEntries scopedEntries = new ScopedAclEntries(featureEntries); IList <AclEntry> parentDefaultEntries = scopedEntries.GetDefaultEntries(); // The parent may have an access ACL but no default ACL. If so, exit. if (parentDefaultEntries.IsEmpty()) { return; } // Pre-allocate list size for access entries to copy from parent. IList <AclEntry> accessEntries = Lists.NewArrayListWithCapacity(parentDefaultEntries .Count); FsPermission childPerm = child.GetFsPermission(); // Copy each default ACL entry from parent to new child's access ACL. bool parentDefaultIsMinimal = AclUtil.IsMinimalAcl(parentDefaultEntries); foreach (AclEntry entry in parentDefaultEntries) { AclEntryType type = entry.GetType(); string name = entry.GetName(); AclEntry.Builder builder = new AclEntry.Builder().SetScope(AclEntryScope.Access). SetType(type).SetName(name); // The child's initial permission bits are treated as the mode parameter, // which can filter copied permission values for owner, mask and other. FsAction permission; if (type == AclEntryType.User && name == null) { permission = entry.GetPermission().And(childPerm.GetUserAction()); } else { if (type == AclEntryType.Group && parentDefaultIsMinimal) { // This only happens if the default ACL is a minimal ACL: exactly 3 // entries corresponding to owner, group and other. In this case, // filter the group permissions. permission = entry.GetPermission().And(childPerm.GetGroupAction()); } else { if (type == AclEntryType.Mask) { // Group bits from mode parameter filter permission of mask entry. permission = entry.GetPermission().And(childPerm.GetGroupAction()); } else { if (type == AclEntryType.Other) { permission = entry.GetPermission().And(childPerm.GetOtherAction()); } else { permission = entry.GetPermission(); } } } } builder.SetPermission(permission); accessEntries.AddItem(builder.Build()); } // A new directory also receives a copy of the parent's default ACL. IList <AclEntry> defaultEntries = child.IsDirectory() ? parentDefaultEntries : Sharpen.Collections .EmptyList <AclEntry>(); FsPermission newPerm; if (!AclUtil.IsMinimalAcl(accessEntries) || !defaultEntries.IsEmpty()) { // Save the new ACL to the child. child.AddAclFeature(CreateAclFeature(accessEntries, defaultEntries)); newPerm = CreateFsPermissionForExtendedAcl(accessEntries, childPerm); } else { // The child is receiving a minimal ACL. newPerm = CreateFsPermissionForMinimalAcl(accessEntries, childPerm); } child.SetPermission(newPerm); }