public virtual void TestInternalGetAclStatus() { UserGroupInformation currentUser = UserGroupInformation.GetCurrentUser(); AclStatus aclStatus = fsView.GetAclStatus(new Path("/internalDir")); Assert.Equal(aclStatus.GetOwner(), currentUser.GetUserName()); Assert.Equal(aclStatus.GetGroup(), currentUser.GetGroupNames() [0]); Assert.Equal(aclStatus.GetEntries(), AclUtil.GetMinimalAcl(Constants .Permission555)); NUnit.Framework.Assert.IsFalse(aclStatus.IsStickyBit()); }
// last ditch effort to ensure temp file is removed /// <summary>Preserve the attributes of the source to the target.</summary> /// <remarks> /// Preserve the attributes of the source to the target. /// The method calls /// <see cref="ShouldPreserve(FileAttribute)"/> /// to check what /// attribute to preserve. /// </remarks> /// <param name="src">source to preserve</param> /// <param name="target">where to preserve attributes</param> /// <param name="preserveRawXAttrs">true if raw.* xattrs should be preserved</param> /// <exception cref="System.IO.IOException">if fails to preserve attributes</exception> protected internal virtual void PreserveAttributes(PathData src, PathData target, bool preserveRawXAttrs) { if (ShouldPreserve(CommandWithDestination.FileAttribute.Timestamps)) { target.fs.SetTimes(target.path, src.stat.GetModificationTime(), src.stat.GetAccessTime ()); } if (ShouldPreserve(CommandWithDestination.FileAttribute.Ownership)) { target.fs.SetOwner(target.path, src.stat.GetOwner(), src.stat.GetGroup()); } if (ShouldPreserve(CommandWithDestination.FileAttribute.Permission) || ShouldPreserve (CommandWithDestination.FileAttribute.Acl)) { target.fs.SetPermission(target.path, src.stat.GetPermission()); } if (ShouldPreserve(CommandWithDestination.FileAttribute.Acl)) { FsPermission perm = src.stat.GetPermission(); if (perm.GetAclBit()) { IList <AclEntry> srcEntries = src.fs.GetAclStatus(src.path).GetEntries(); IList <AclEntry> srcFullEntries = AclUtil.GetAclFromPermAndEntries(perm, srcEntries ); target.fs.SetAcl(target.path, srcFullEntries); } } bool preserveXAttrs = ShouldPreserve(CommandWithDestination.FileAttribute.Xattr); if (preserveXAttrs || preserveRawXAttrs) { IDictionary <string, byte[]> srcXAttrs = src.fs.GetXAttrs(src.path); if (srcXAttrs != null) { IEnumerator <KeyValuePair <string, byte[]> > iter = srcXAttrs.GetEnumerator(); while (iter.HasNext()) { KeyValuePair <string, byte[]> entry = iter.Next(); string xattrName = entry.Key; if (xattrName.StartsWith(Raw) || preserveXAttrs) { target.fs.SetXAttr(target.path, entry.Key, entry.Value); } } } } }
/// <summary>Reads the existing ACL of an inode.</summary> /// <remarks> /// Reads the existing ACL of an inode. This method always returns the full /// logical ACL of the inode after reading relevant data from the inode's /// <see cref="Org.Apache.Hadoop.FS.Permission.FsPermission"/> /// and /// <see cref="AclFeature"/> /// . Note that every inode /// logically has an ACL, even if no ACL has been set explicitly. If the inode /// does not have an extended ACL, then the result is a minimal ACL consising of /// exactly 3 entries that correspond to the owner, group and other permissions. /// This method always reads the inode's current state and does not support /// querying by snapshot ID. This is because the method is intended to support /// ACL modification APIs, which always apply a delta on top of current state. /// </remarks> /// <param name="inode">INode to read</param> /// <returns>List<AclEntry> containing all logical inode ACL entries</returns> public static IList <AclEntry> ReadINodeLogicalAcl(INode inode) { FsPermission perm = inode.GetFsPermission(); AclFeature f = inode.GetAclFeature(); if (f == null) { return(AclUtil.GetMinimalAcl(perm)); } IList <AclEntry> existingAcl; // Split ACL entries stored in the feature into access vs. default. IList <AclEntry> featureEntries = GetEntriesFromAclFeature(f); ScopedAclEntries scoped = new ScopedAclEntries(featureEntries); IList <AclEntry> accessEntries = scoped.GetAccessEntries(); IList <AclEntry> defaultEntries = scoped.GetDefaultEntries(); // Pre-allocate list size for the explicit entries stored in the feature // plus the 3 implicit entries (owner, group and other) from the permission // bits. existingAcl = Lists.NewArrayListWithCapacity(featureEntries.Count + 3); if (!accessEntries.IsEmpty()) { // Add owner entry implied from user permission bits. existingAcl.AddItem(new AclEntry.Builder().SetScope(AclEntryScope.Access).SetType (AclEntryType.User).SetPermission(perm.GetUserAction()).Build()); // Next add all named user and group entries taken from the feature. Sharpen.Collections.AddAll(existingAcl, accessEntries); // Add mask entry implied from group permission bits. existingAcl.AddItem(new AclEntry.Builder().SetScope(AclEntryScope.Access).SetType (AclEntryType.Mask).SetPermission(perm.GetGroupAction()).Build()); // Add other entry implied from other permission bits. existingAcl.AddItem(new AclEntry.Builder().SetScope(AclEntryScope.Access).SetType (AclEntryType.Other).SetPermission(perm.GetOtherAction()).Build()); } else { // It's possible that there is a default ACL but no access ACL. In this // case, add the minimal access ACL implied by the permission bits. Sharpen.Collections.AddAll(existingAcl, AclUtil.GetMinimalAcl(perm)); } // Add all default entries after the access entries. Sharpen.Collections.AddAll(existingAcl, defaultEntries); // The above adds entries in the correct order, so no need to sort here. return(existingAcl); }
/// <summary>Creates an AclFeature from the given ACL entries.</summary> /// <param name="accessEntries">List<AclEntry> access ACL entries</param> /// <param name="defaultEntries">List<AclEntry> default ACL entries</param> /// <returns>AclFeature containing the required ACL entries</returns> private static AclFeature CreateAclFeature(IList <AclEntry> accessEntries, IList <AclEntry > defaultEntries) { // Pre-allocate list size for the explicit entries stored in the feature, // which is all entries minus the 3 entries implicitly stored in the // permission bits. IList <AclEntry> featureEntries = Lists.NewArrayListWithCapacity((accessEntries.Count - 3) + defaultEntries.Count); // For the access ACL, the feature only needs to hold the named user and // group entries. For a correctly sorted ACL, these will be in a // predictable range. if (!AclUtil.IsMinimalAcl(accessEntries)) { Sharpen.Collections.AddAll(featureEntries, accessEntries.SubList(1, accessEntries .Count - 2)); } // Add all default entries to the feature. Sharpen.Collections.AddAll(featureEntries, defaultEntries); return(new AclFeature(AclEntryStatusFormat.ToInt(featureEntries))); }
/// <summary>Prints all the ACL entries in a single scope.</summary> /// <param name="aclStatus">AclStatus for the path</param> /// <param name="fsPerm">FsPermission for the path</param> /// <param name="entries">List<AclEntry> containing ACL entries of file</param> private void PrintAclEntriesForSingleScope(AclStatus aclStatus, FsPermission fsPerm , IList <AclEntry> entries) { if (entries.IsEmpty()) { return; } if (AclUtil.IsMinimalAcl(entries)) { foreach (AclEntry entry in entries) { @out.WriteLine(entry); } } else { foreach (AclEntry entry in entries) { PrintExtendedAclEntry(aclStatus, fsPerm, entry); } } }
/// <exception cref="System.IO.IOException"/> protected internal override void ProcessPath(PathData item) { @out.WriteLine("# file: " + item); @out.WriteLine("# owner: " + item.stat.GetOwner()); @out.WriteLine("# group: " + item.stat.GetGroup()); FsPermission perm = item.stat.GetPermission(); if (perm.GetStickyBit()) { @out.WriteLine("# flags: --" + (perm.GetOtherAction().Implies(FsAction.Execute) ? "t" : "T")); } AclStatus aclStatus = item.fs.GetAclStatus(item.path); IList <AclEntry> entries = perm.GetAclBit() ? aclStatus.GetEntries() : Collections .EmptyList <AclEntry>(); ScopedAclEntries scopedEntries = new ScopedAclEntries(AclUtil.GetAclFromPermAndEntries (perm, entries)); PrintAclEntriesForSingleScope(aclStatus, perm, scopedEntries.GetAccessEntries()); PrintAclEntriesForSingleScope(aclStatus, perm, scopedEntries.GetDefaultEntries()); @out.WriteLine(); }
/// <summary>Updates an inode with a new ACL.</summary> /// <remarks> /// Updates an inode with a new ACL. This method takes a full logical ACL and /// stores the entries to the inode's /// <see cref="Org.Apache.Hadoop.FS.Permission.FsPermission"/> /// and /// <see cref="AclFeature"/> /// . /// </remarks> /// <param name="inode">INode to update</param> /// <param name="newAcl">List<AclEntry> containing new ACL entries</param> /// <param name="snapshotId">int latest snapshot ID of inode</param> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.AclException">if the ACL is invalid for the given inode /// </exception> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException">if quota limit is exceeded /// </exception> public static void UpdateINodeAcl(INode inode, IList <AclEntry> newAcl, int snapshotId ) { System.Diagnostics.Debug.Assert(newAcl.Count >= 3); FsPermission perm = inode.GetFsPermission(); FsPermission newPerm; if (!AclUtil.IsMinimalAcl(newAcl)) { // This is an extended ACL. Split entries into access vs. default. ScopedAclEntries scoped = new ScopedAclEntries(newAcl); IList <AclEntry> accessEntries = scoped.GetAccessEntries(); IList <AclEntry> defaultEntries = scoped.GetDefaultEntries(); // Only directories may have a default ACL. if (!defaultEntries.IsEmpty() && !inode.IsDirectory()) { throw new AclException("Invalid ACL: only directories may have a default ACL."); } // Attach entries to the feature. if (inode.GetAclFeature() != null) { inode.RemoveAclFeature(snapshotId); } inode.AddAclFeature(CreateAclFeature(accessEntries, defaultEntries), snapshotId); newPerm = CreateFsPermissionForExtendedAcl(accessEntries, perm); } else { // This is a minimal ACL. Remove the ACL feature if it previously had one. if (inode.GetAclFeature() != null) { inode.RemoveAclFeature(snapshotId); } newPerm = CreateFsPermissionForMinimalAcl(newAcl, perm); } inode.SetPermission(newPerm, snapshotId); }
/// <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); }
/// <exception cref="System.IO.IOException"/> public override AclStatus GetAclStatus(Path path) { CheckPathIsSlash(path); return(new AclStatus.Builder().Owner(ugi.GetUserName()).Group(ugi.GetGroupNames() [0]).AddEntries(AclUtil.GetMinimalAcl(Constants.Permission555)).StickyBit(false) .Build()); }