/// <summary>Check whether current user have permissions to access the path.</summary> /// <remarks> /// Check whether current user have permissions to access the path. /// Traverse is always checked. /// Parent path means the parent directory for the path. /// Ancestor path means the last (the closest) existing ancestor directory /// of the path. /// Note that if the parent path exists, /// then the parent path and the ancestor path are the same. /// For example, suppose the path is "/foo/bar/baz". /// No matter baz is a file or a directory, /// the parent path is "/foo/bar". /// If bar exists, then the ancestor path is also "/foo/bar". /// If bar does not exist and foo exists, /// then the ancestor path is "/foo". /// Further, if both foo and bar do not exist, /// then the ancestor path is "/". /// </remarks> /// <param name="doCheckOwner">Require user to be the owner of the path?</param> /// <param name="ancestorAccess">The access required by the ancestor of the path.</param> /// <param name="parentAccess">The access required by the parent of the path.</param> /// <param name="access">The access required by the path.</param> /// <param name="subAccess"> /// If path is a directory, /// it is the access required of the path and all the sub-directories. /// If path is not a directory, there is no effect. /// </param> /// <param name="ignoreEmptyDir">Ignore permission checking for empty directory?</param> /// <exception cref="Org.Apache.Hadoop.Security.AccessControlException"> /// Guarded by /// <see cref="FSNamesystem.ReadLock()"/> /// Caller of this method must hold that lock. /// </exception> internal virtual void CheckPermission(INodesInPath inodesInPath, bool doCheckOwner , FsAction ancestorAccess, FsAction parentAccess, FsAction access, FsAction subAccess , bool ignoreEmptyDir) { if (Log.IsDebugEnabled()) { Log.Debug("ACCESS CHECK: " + this + ", doCheckOwner=" + doCheckOwner + ", ancestorAccess=" + ancestorAccess + ", parentAccess=" + parentAccess + ", access=" + access + ", subAccess=" + subAccess + ", ignoreEmptyDir=" + ignoreEmptyDir); } // check if (parentAccess != null) && file exists, then check sb // If resolveLink, the check is performed on the link target. int snapshotId = inodesInPath.GetPathSnapshotId(); INode[] inodes = inodesInPath.GetINodesArray(); INodeAttributes[] inodeAttrs = new INodeAttributes[inodes.Length]; byte[][] pathByNameArr = new byte[inodes.Length][]; for (int i = 0; i < inodes.Length && inodes[i] != null; i++) { if (inodes[i] != null) { pathByNameArr[i] = inodes[i].GetLocalNameBytes(); inodeAttrs[i] = GetINodeAttrs(pathByNameArr, i, inodes[i], snapshotId); } } string path = inodesInPath.GetPath(); int ancestorIndex = inodes.Length - 2; INodeAttributeProvider.AccessControlEnforcer enforcer = GetAttributesProvider().GetExternalAccessControlEnforcer (this); enforcer.CheckPermission(fsOwner, supergroup, callerUgi, inodeAttrs, inodes, pathByNameArr , snapshotId, path, ancestorIndex, doCheckOwner, ancestorAccess, parentAccess, access , subAccess, ignoreEmptyDir); }
/// <exception cref="System.IO.IOException"/> private static void WritePermissionStatus(INodeAttributes inode, DataOutput @out) { FsPermission p = TlData.Get().FilePerm; p.FromShort(inode.GetFsPermissionShort()); PermissionStatus.Write(@out, inode.GetUserName(), inode.GetGroupName(), p); }
/// <summary>Create FileStatus by file INode</summary> /// <exception cref="System.IO.IOException"/> internal static HdfsFileStatus CreateFileStatus(FSDirectory fsd, string fullPath, byte[] path, INode node, byte storagePolicy, int snapshot, bool isRawPath, INodesInPath iip) { long size = 0; // length is zero for directories short replication = 0; long blocksize = 0; bool isEncrypted; FileEncryptionInfo feInfo = isRawPath ? null : fsd.GetFileEncryptionInfo(node, snapshot , iip); if (node.IsFile()) { INodeFile fileNode = node.AsFile(); size = fileNode.ComputeFileSize(snapshot); replication = fileNode.GetFileReplication(snapshot); blocksize = fileNode.GetPreferredBlockSize(); isEncrypted = (feInfo != null) || (isRawPath && fsd.IsInAnEZ(INodesInPath.FromINode (node))); } else { isEncrypted = fsd.IsInAnEZ(INodesInPath.FromINode(node)); } int childrenNum = node.IsDirectory() ? node.AsDirectory().GetChildrenNum(snapshot ) : 0; INodeAttributes nodeAttrs = fsd.GetAttributes(fullPath, path, node, snapshot); return(new HdfsFileStatus(size, node.IsDirectory(), replication, blocksize, node. GetModificationTime(snapshot), node.GetAccessTime(snapshot), GetPermissionForFileStatus (nodeAttrs, isEncrypted), nodeAttrs.GetUserName(), nodeAttrs.GetGroupName(), node .IsSymlink() ? node.AsSymlink().GetSymlink() : null, path, node.GetId(), childrenNum , feInfo, storagePolicy)); }
/// <summary>Create FileStatus with location info by file INode</summary> /// <exception cref="System.IO.IOException"/> private static HdfsLocatedFileStatus CreateLocatedFileStatus(FSDirectory fsd, string fullPath, byte[] path, INode node, byte storagePolicy, int snapshot, bool isRawPath , INodesInPath iip) { System.Diagnostics.Debug.Assert(fsd.HasReadLock()); long size = 0; // length is zero for directories short replication = 0; long blocksize = 0; LocatedBlocks loc = null; bool isEncrypted; FileEncryptionInfo feInfo = isRawPath ? null : fsd.GetFileEncryptionInfo(node, snapshot , iip); if (node.IsFile()) { INodeFile fileNode = node.AsFile(); size = fileNode.ComputeFileSize(snapshot); replication = fileNode.GetFileReplication(snapshot); blocksize = fileNode.GetPreferredBlockSize(); bool inSnapshot = snapshot != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot .CurrentStateId; bool isUc = !inSnapshot && fileNode.IsUnderConstruction(); long fileSize = !inSnapshot && isUc?fileNode.ComputeFileSizeNotIncludingLastUcBlock () : size; loc = fsd.GetFSNamesystem().GetBlockManager().CreateLocatedBlocks(fileNode.GetBlocks (snapshot), fileSize, isUc, 0L, size, false, inSnapshot, feInfo); if (loc == null) { loc = new LocatedBlocks(); } isEncrypted = (feInfo != null) || (isRawPath && fsd.IsInAnEZ(INodesInPath.FromINode (node))); } else { isEncrypted = fsd.IsInAnEZ(INodesInPath.FromINode(node)); } int childrenNum = node.IsDirectory() ? node.AsDirectory().GetChildrenNum(snapshot ) : 0; INodeAttributes nodeAttrs = fsd.GetAttributes(fullPath, path, node, snapshot); HdfsLocatedFileStatus status = new HdfsLocatedFileStatus(size, node.IsDirectory() , replication, blocksize, node.GetModificationTime(snapshot), node.GetAccessTime (snapshot), GetPermissionForFileStatus(nodeAttrs, isEncrypted), nodeAttrs.GetUserName (), nodeAttrs.GetGroupName(), node.IsSymlink() ? node.AsSymlink().GetSymlink() : null, path, node.GetId(), loc, childrenNum, feInfo, storagePolicy); // Set caching information for the located blocks. if (loc != null) { CacheManager cacheManager = fsd.GetFSNamesystem().GetCacheManager(); foreach (LocatedBlock lb in loc.GetLocatedBlocks()) { cacheManager.SetCachedLocations(lb); } } return(status); }
public override INodeAttributes GetAttributes(string[] pathElements, INodeAttributes inode) { Called.AddItem("getAttributes"); bool useDefault = UseDefault(pathElements); return(new _INodeAttributes_80(inode, useDefault)); }
/// <summary> /// Guarded by /// <see cref="FSNamesystem.ReadLock()"/> /// /// </summary> /// <exception cref="Org.Apache.Hadoop.Security.AccessControlException"/> private void CheckOwner(INodeAttributes inode) { if (GetUser().Equals(inode.GetUserName())) { return; } throw new AccessControlException("Permission denied. user="******" is not the owner of inode=" + inode); }
private static long BuildPermissionStatus(INodeAttributes n, FSImageFormatProtobuf.SaverContext.DeduplicationMap <string> stringMap) { long userId = stringMap.GetId(n.GetUserName()); long groupId = stringMap.GetId(n.GetGroupName()); return(((userId & UserGroupStridMask) << UserStridOffset) | ((groupId & UserGroupStridMask ) << GroupStridOffset) | n.GetFsPermissionShort()); }
/// <summary>Returns an inode's FsPermission for use in an outbound FileStatus.</summary> /// <remarks> /// Returns an inode's FsPermission for use in an outbound FileStatus. If the /// inode has an ACL or is for an encrypted file/dir, then this method will /// return an FsPermissionExtension. /// </remarks> /// <param name="node">INode to check</param> /// <param name="snapshot">int snapshot ID</param> /// <param name="isEncrypted">boolean true if the file/dir is encrypted</param> /// <returns> /// FsPermission from inode, with ACL bit on if the inode has an ACL /// and encrypted bit on if it represents an encrypted file/dir. /// </returns> private static FsPermission GetPermissionForFileStatus(INodeAttributes node, bool isEncrypted) { FsPermission perm = node.GetFsPermission(); bool hasAcl = node.GetAclFeature() != null; if (hasAcl || isEncrypted) { perm = new FsPermissionExtension(perm, hasAcl, isEncrypted); } return(perm); }
/// <exception cref="Org.Apache.Hadoop.Security.AccessControlException"/> private void Check(INodeAttributes inode, string path, FsAction access) { if (inode == null) { return; } FsPermission mode = inode.GetFsPermission(); AclFeature aclFeature = inode.GetAclFeature(); if (aclFeature != null) { // It's possible that the inode has a default ACL but no access ACL. int firstEntry = aclFeature.GetEntryAt(0); if (AclEntryStatusFormat.GetScope(firstEntry) == AclEntryScope.Access) { CheckAccessAcl(inode, path, access, mode, aclFeature); return; } } if (GetUser().Equals(inode.GetUserName())) { //user class if (mode.GetUserAction().Implies(access)) { return; } } else { if (GetGroups().Contains(inode.GetGroupName())) { //group class if (mode.GetGroupAction().Implies(access)) { return; } } else { //other class if (mode.GetOtherAction().Implies(access)) { return; } } } throw new AccessControlException(ToAccessControlString(inode, path, access, mode) ); }
/// <returns> /// a string for throwing /// <see cref="Org.Apache.Hadoop.Security.AccessControlException"/> /// /// </returns> private string ToAccessControlString(INodeAttributes inodeAttrib, string path, FsAction access, FsPermission mode, bool deniedFromAcl) { StringBuilder sb = new StringBuilder("Permission denied: ").Append("user="******", ").Append("access=").Append(access).Append(", ").Append("inode=\"" ).Append(path).Append("\":").Append(inodeAttrib.GetUserName()).Append(':').Append (inodeAttrib.GetGroupName()).Append(':').Append(inodeAttrib.IsDirectory() ? 'd' : '-').Append(mode); if (deniedFromAcl) { sb.Append("+"); } return(sb.ToString()); }
private INodeAttributes GetINodeAttrs(byte[][] pathByNameArr, int pathIdx, INode inode, int snapshotId) { INodeAttributes inodeAttrs = inode.GetSnapshotINode(snapshotId); if (GetAttributesProvider() != null) { string[] elements = new string[pathIdx + 1]; for (int i = 0; i < elements.Length; i++) { elements[i] = DFSUtil.Bytes2String(pathByNameArr[i]); } inodeAttrs = GetAttributesProvider().GetAttributes(elements, inodeAttrs); } return(inodeAttrs); }
/// <summary> /// Guarded by /// <see cref="FSNamesystem.ReadLock()"/> /// /// </summary> /// <exception cref="Org.Apache.Hadoop.Security.AccessControlException"/> private void CheckStickyBit(INodeAttributes parent, INodeAttributes inode) { if (!parent.GetFsPermission().GetStickyBit()) { return; } // If this user is the directory owner, return if (parent.GetUserName().Equals(GetUser())) { return; } // if this user is the file owner, return if (inode.GetUserName().Equals(GetUser())) { return; } throw new AccessControlException("Permission denied by sticky bit setting:" + " user="******", inode=" + inode); }
/// <exception cref="Org.Apache.Hadoop.Security.AccessControlException"/> public virtual void CheckPermission(string fsOwner, string supergroup, UserGroupInformation callerUgi, INodeAttributes[] inodeAttrs, INode[] inodes, byte[][] pathByNameArr , int snapshotId, string path, int ancestorIndex, bool doCheckOwner, FsAction ancestorAccess , FsAction parentAccess, FsAction access, FsAction subAccess, bool ignoreEmptyDir ) { for (; ancestorIndex >= 0 && inodes[ancestorIndex] == null; ancestorIndex--) { } CheckTraverse(inodeAttrs, path, ancestorIndex); INodeAttributes last = inodeAttrs[inodeAttrs.Length - 1]; if (parentAccess != null && parentAccess.Implies(FsAction.Write) && inodeAttrs.Length > 1 && last != null) { CheckStickyBit(inodeAttrs[inodeAttrs.Length - 2], last); } if (ancestorAccess != null && inodeAttrs.Length > 1) { Check(inodeAttrs, path, ancestorIndex, ancestorAccess); } if (parentAccess != null && inodeAttrs.Length > 1) { Check(inodeAttrs, path, inodeAttrs.Length - 2, parentAccess); } if (access != null) { Check(last, path, access); } if (subAccess != null) { INode rawLast = inodes[inodeAttrs.Length - 1]; CheckSubAccess(pathByNameArr, inodeAttrs.Length - 1, rawLast, snapshotId, subAccess , ignoreEmptyDir); } if (doCheckOwner) { CheckOwner(last); } }
/// <exception cref="System.IO.IOException"/> private static void WriteLocalName(INodeAttributes inode, DataOutput @out) { byte[] name = inode.GetLocalNameBytes(); WriteBytes(name, @out); }
// NO-OP public override INodeAttributes GetAttributes(string[] pathElements, INodeAttributes inode) { return(inode); }
public virtual INodeAttributes GetAttributes(string fullPath, INodeAttributes inode ) { return(GetAttributes(GetPathElements(fullPath), inode)); }
public abstract INodeAttributes GetAttributes(string[] pathElements, INodeAttributes inode);
/// <summary>Reads the existing extended ACL entries of an INodeAttribute object.</summary> /// <param name="inodeAttr">INode to read</param> /// <returns>List<AclEntry> containing extended inode ACL entries</returns> public static IList <AclEntry> ReadINodeAcl(INodeAttributes inodeAttr) { AclFeature f = inodeAttr.GetAclFeature(); return(GetEntriesFromAclFeature(f)); }
/// <summary>Reads the existing extended attributes of an inode.</summary> /// <remarks> /// Reads the existing extended attributes of an inode. /// <p/> /// Must be called while holding the FSDirectory read lock. /// </remarks> /// <param name="inodeAttr">INodeAttributes to read.</param> /// <returns>List<XAttr> <code>XAttr</code> list.</returns> public static IList <XAttr> ReadINodeXAttrs(INodeAttributes inodeAttr) { XAttrFeature f = inodeAttr.GetXAttrFeature(); return(f == null?ImmutableList.Of <XAttr>() : f.GetXAttrs()); }
public _INodeAttributes_80(INodeAttributes inode, bool useDefault) { this.inode = inode; this.useDefault = useDefault; }
/// <returns> /// a string for throwing /// <see cref="Org.Apache.Hadoop.Security.AccessControlException"/> /// /// </returns> private string ToAccessControlString(INodeAttributes inodeAttrib, string path, FsAction access, FsPermission mode) { return(ToAccessControlString(inodeAttrib, path, access, mode, false)); }
/// <summary>Checks requested access against an Access Control List.</summary> /// <remarks> /// Checks requested access against an Access Control List. This method relies /// on finding the ACL data in the relevant portions of /// <see cref="Org.Apache.Hadoop.FS.Permission.FsPermission"/> /// and /// <see cref="AclFeature"/> /// as implemented in the logic of /// <see cref="AclStorage"/> /// . This /// method also relies on receiving the ACL entries in sorted order. This is /// assumed to be true, because the ACL modification methods in /// <see cref="AclTransformation"/> /// sort the resulting entries. /// More specifically, this method depends on these invariants in an ACL: /// - The list must be sorted. /// - Each entry in the list must be unique by scope + type + name. /// - There is exactly one each of the unnamed user/group/other entries. /// - The mask entry must not have a name. /// - The other entry must not have a name. /// - Default entries may be present, but they are ignored during enforcement. /// </remarks> /// <param name="inode">INodeAttributes accessed inode</param> /// <param name="snapshotId">int snapshot ID</param> /// <param name="access">FsAction requested permission</param> /// <param name="mode">FsPermission mode from inode</param> /// <param name="aclFeature">AclFeature of inode</param> /// <exception cref="Org.Apache.Hadoop.Security.AccessControlException">if the ACL denies permission /// </exception> private void CheckAccessAcl(INodeAttributes inode, string path, FsAction access, FsPermission mode, AclFeature aclFeature) { bool foundMatch = false; // Use owner entry from permission bits if user is owner. if (GetUser().Equals(inode.GetUserName())) { if (mode.GetUserAction().Implies(access)) { return; } foundMatch = true; } // Check named user and group entries if user was not denied by owner entry. if (!foundMatch) { for (int pos = 0; pos < aclFeature.GetEntriesSize(); pos++) { entry = aclFeature.GetEntryAt(pos); if (AclEntryStatusFormat.GetScope(entry) == AclEntryScope.Default) { break; } AclEntryType type = AclEntryStatusFormat.GetType(entry); string name = AclEntryStatusFormat.GetName(entry); if (type == AclEntryType.User) { // Use named user entry with mask from permission bits applied if user // matches name. if (GetUser().Equals(name)) { FsAction masked = AclEntryStatusFormat.GetPermission(entry).And(mode.GetGroupAction ()); if (masked.Implies(access)) { return; } foundMatch = true; break; } } else { if (type == AclEntryType.Group) { // Use group entry (unnamed or named) with mask from permission bits // applied if user is a member and entry grants access. If user is a // member of multiple groups that have entries that grant access, then // it doesn't matter which is chosen, so exit early after first match. string group = name == null?inode.GetGroupName() : name; if (GetGroups().Contains(group)) { FsAction masked = AclEntryStatusFormat.GetPermission(entry).And(mode.GetGroupAction ()); if (masked.Implies(access)) { return; } foundMatch = true; } } } } } // Use other entry if user was not denied by an earlier match. if (!foundMatch && mode.GetOtherAction().Implies(access)) { return; } throw new AccessControlException(ToAccessControlString(inode, path, access, mode) ); }