private FsAction GetFsAction(int accessGroup, FTPFile ftpFile) { FsAction action = FsAction.None; if (ftpFile.HasPermission(accessGroup, FTPFile.ReadPermission)) { action.Or(FsAction.Read); } if (ftpFile.HasPermission(accessGroup, FTPFile.WritePermission)) { action.Or(FsAction.Write); } if (ftpFile.HasPermission(accessGroup, FTPFile.ExecutePermission)) { action.Or(FsAction.Execute); } return(action); }
/// <summary>Calculates mask entries required for the ACL.</summary> /// <remarks> /// Calculates mask entries required for the ACL. Mask calculation is performed /// separately for each scope: access and default. This method is responsible /// for handling the following cases of mask calculation: /// 1. Throws an exception if the caller attempts to remove the mask entry of an /// existing ACL that requires it. If the ACL has any named entries, then a /// mask entry is required. /// 2. If the caller supplied a mask in the ACL spec, use it. /// 3. If the caller did not supply a mask, but there are ACL entry changes in /// this scope, then automatically calculate a new mask. The permissions of /// the new mask are the union of the permissions on the group entry and all /// named entries. /// </remarks> /// <param name="aclBuilder">ArrayList<AclEntry> containing entries to build</param> /// <param name="providedMask"> /// EnumMap<AclEntryScope, AclEntry> mapping each scope to /// the mask entry that was provided for that scope (if provided) /// </param> /// <param name="maskDirty"> /// EnumSet<AclEntryScope> which contains a scope if the mask /// entry is dirty (added or deleted) in that scope /// </param> /// <param name="scopeDirty"> /// EnumSet<AclEntryScope> which contains a scope if any entry /// is dirty (added or deleted) in that scope /// </param> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.AclException">if validation fails /// </exception> private static void CalculateMasks(IList <AclEntry> aclBuilder, EnumMap <AclEntryScope , AclEntry> providedMask, EnumSet <AclEntryScope> maskDirty, EnumSet <AclEntryScope > scopeDirty) { EnumSet <AclEntryScope> scopeFound = EnumSet.NoneOf <AclEntryScope>(); EnumMap <AclEntryScope, FsAction> unionPerms = Maps.NewEnumMap <AclEntryScope>(); EnumSet <AclEntryScope> maskNeeded = EnumSet.NoneOf <AclEntryScope>(); // Determine which scopes are present, which scopes need a mask, and the // union of group class permissions in each scope. foreach (AclEntry entry in aclBuilder) { scopeFound.AddItem(entry.GetScope()); if (entry.GetType() == AclEntryType.Group || entry.GetName() != null) { FsAction scopeUnionPerms = Objects.FirstNonNull(unionPerms[entry.GetScope()], FsAction .None); unionPerms[entry.GetScope()] = scopeUnionPerms.Or(entry.GetPermission()); } if (entry.GetName() != null) { maskNeeded.AddItem(entry.GetScope()); } } // Add mask entry if needed in each scope. foreach (AclEntryScope scope in scopeFound) { if (!providedMask.Contains(scope) && maskNeeded.Contains(scope) && maskDirty.Contains (scope)) { // Caller explicitly removed mask entry, but it's required. throw new AclException("Invalid ACL: mask is required and cannot be deleted."); } else { if (providedMask.Contains(scope) && (!scopeDirty.Contains(scope) || maskDirty.Contains (scope))) { // Caller explicitly provided new mask, or we are preserving the existing // mask in an unchanged scope. aclBuilder.AddItem(providedMask[scope]); } else { if (maskNeeded.Contains(scope) || providedMask.Contains(scope)) { // Otherwise, if there are maskable entries present, or the ACL // previously had a mask, then recalculate a mask automatically. aclBuilder.AddItem(new AclEntry.Builder().SetScope(scope).SetType(AclEntryType.Mask ).SetPermission(unionPerms[scope]).Build()); } } } } }