예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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));
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
            public override INodeAttributes GetAttributes(string[] pathElements, INodeAttributes
                                                          inode)
            {
                Called.AddItem("getAttributes");
                bool useDefault = UseDefault(pathElements);

                return(new _INodeAttributes_80(inode, useDefault));
            }
예제 #6
0
 /// <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);
 }
예제 #7
0
            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());
            }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <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)
                                             );
        }
예제 #10
0
        /// <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());
        }
예제 #11
0
        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);
        }
예제 #12
0
 /// <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);
 }
예제 #13
0
        /// <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);
            }
        }
예제 #14
0
 /// <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);
 }
예제 #16
0
 public virtual INodeAttributes GetAttributes(string fullPath, INodeAttributes inode
                                              )
 {
     return(GetAttributes(GetPathElements(fullPath), inode));
 }
예제 #17
0
 public abstract INodeAttributes GetAttributes(string[] pathElements, INodeAttributes
                                               inode);
예제 #18
0
        /// <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));
        }
예제 #19
0
        /// <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());
        }
예제 #20
0
 public _INodeAttributes_80(INodeAttributes inode, bool useDefault)
 {
     this.inode      = inode;
     this.useDefault = useDefault;
 }
예제 #21
0
 /// <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));
 }
예제 #22
0
        /// <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)
                                             );
        }