Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
        }