/// <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); }
internal SnapshotCopy(INode inode) { this.name = inode.GetLocalNameBytes(); this.permission = inode.GetPermissionLong(); if (inode.GetAclFeature() != null) { aclFeature = AclStorage.AddAclFeature(inode.GetAclFeature()); } else { aclFeature = null; } this.modificationTime = inode.GetModificationTime(); this.accessTime = inode.GetAccessTime(); this.xAttrFeature = inode.GetXAttrFeature(); }
/// <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>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>Reads the existing extended ACL entries of an inode.</summary> /// <remarks> /// Reads the existing extended ACL entries of an inode. This method returns /// only the extended ACL entries stored in the AclFeature. If the inode does /// not have an ACL, then this method returns an empty list. This method /// supports querying by snapshot ID. /// </remarks> /// <param name="inode">INode to read</param> /// <param name="snapshotId">int ID of snapshot to read</param> /// <returns>List<AclEntry> containing extended inode ACL entries</returns> public static IList <AclEntry> ReadINodeAcl(INode inode, int snapshotId) { AclFeature f = inode.GetAclFeature(snapshotId); return(GetEntriesFromAclFeature(f)); }