/// <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); }
/// <exception cref="System.IO.FileNotFoundException"/> /// <exception cref="Org.Apache.Hadoop.FS.UnresolvedLinkException"/> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException"/> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.SnapshotAccessControlException"/ /// > internal static void UnprotectedSetPermission(FSDirectory fsd, string src, FsPermission permissions) { System.Diagnostics.Debug.Assert(fsd.HasWriteLock()); INodesInPath inodesInPath = fsd.GetINodesInPath4Write(src, true); INode inode = inodesInPath.GetLastINode(); if (inode == null) { throw new FileNotFoundException("File does not exist: " + src); } int snapshotId = inodesInPath.GetLatestSnapshotId(); inode.SetPermission(permissions, snapshotId); }
/// <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); }