Search in sources :

Example 11 with FsAction

use of org.apache.hadoop.fs.permission.FsAction in project hadoop by apache.

the class FileUtil method setPermission.

/**
   * Set permissions to the required value. Uses the java primitives instead
   * of forking if group == other.
   * @param f the file to change
   * @param permission the new permissions
   * @throws IOException
   */
public static void setPermission(File f, FsPermission permission) throws IOException {
    FsAction user = permission.getUserAction();
    FsAction group = permission.getGroupAction();
    FsAction other = permission.getOtherAction();
    // or if the native is available or on Windows
    if (group != other || NativeIO.isAvailable() || Shell.WINDOWS) {
        execSetPermission(f, permission);
        return;
    }
    boolean rv = true;
    // read perms
    rv = f.setReadable(group.implies(FsAction.READ), false);
    checkReturnValue(rv, f, permission);
    if (group.implies(FsAction.READ) != user.implies(FsAction.READ)) {
        rv = f.setReadable(user.implies(FsAction.READ), true);
        checkReturnValue(rv, f, permission);
    }
    // write perms
    rv = f.setWritable(group.implies(FsAction.WRITE), false);
    checkReturnValue(rv, f, permission);
    if (group.implies(FsAction.WRITE) != user.implies(FsAction.WRITE)) {
        rv = f.setWritable(user.implies(FsAction.WRITE), true);
        checkReturnValue(rv, f, permission);
    }
    // exec perms
    rv = f.setExecutable(group.implies(FsAction.EXECUTE), false);
    checkReturnValue(rv, f, permission);
    if (group.implies(FsAction.EXECUTE) != user.implies(FsAction.EXECUTE)) {
        rv = f.setExecutable(user.implies(FsAction.EXECUTE), true);
        checkReturnValue(rv, f, permission);
    }
}
Also used : FsAction(org.apache.hadoop.fs.permission.FsAction)

Example 12 with FsAction

use of org.apache.hadoop.fs.permission.FsAction in project hadoop by apache.

the class AclStorage method copyINodeDefaultAcl.

/**
   * If a default ACL is defined on a parent directory, then copies that default
   * ACL to a newly created child file or directory.
   *
   * @param child INode newly created child
   */
public static boolean copyINodeDefaultAcl(INode child) {
    INodeDirectory parent = child.getParent();
    AclFeature parentAclFeature = parent.getAclFeature();
    if (parentAclFeature == null || !(child.isFile() || child.isDirectory())) {
        return false;
    }
    // Split parent's entries into access vs. default.
    List<AclEntry> featureEntries = getEntriesFromAclFeature(parent.getAclFeature());
    ScopedAclEntries scopedEntries = new ScopedAclEntries(featureEntries);
    List<AclEntry> parentDefaultEntries = scopedEntries.getDefaultEntries();
    // The parent may have an access ACL but no default ACL.  If so, exit.
    if (parentDefaultEntries.isEmpty()) {
        return false;
    }
    // Pre-allocate list size for access entries to copy from parent.
    List<AclEntry> accessEntries = Lists.newArrayListWithCapacity(parentDefaultEntries.size());
    FsPermission childPerm = child.getFsPermission();
    // Copy each default ACL entry from parent to new child's access ACL.
    boolean parentDefaultIsMinimal = AclUtil.isMinimalAcl(parentDefaultEntries);
    for (AclEntry entry : 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.
        final 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.add(builder.build());
    }
    // A new directory also receives a copy of the parent's default ACL.
    List<AclEntry> defaultEntries = child.isDirectory() ? parentDefaultEntries : Collections.<AclEntry>emptyList();
    final 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);
    return true;
}
Also used : FsAction(org.apache.hadoop.fs.permission.FsAction) ScopedAclEntries(org.apache.hadoop.fs.permission.ScopedAclEntries) AclEntryType(org.apache.hadoop.fs.permission.AclEntryType) AclEntry(org.apache.hadoop.fs.permission.AclEntry) FsPermission(org.apache.hadoop.fs.permission.FsPermission)

Example 13 with FsAction

use of org.apache.hadoop.fs.permission.FsAction in project hadoop by apache.

the class AclTransformation method calculateMasks.

/**
   * 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.
   *
   * @param aclBuilder ArrayList<AclEntry> containing entries to build
   * @param providedMask EnumMap<AclEntryScope, AclEntry> mapping each scope to
   *   the mask entry that was provided for that scope (if provided)
   * @param maskDirty EnumSet<AclEntryScope> which contains a scope if the mask
   *   entry is dirty (added or deleted) in that scope
   * @param scopeDirty EnumSet<AclEntryScope> which contains a scope if any entry
   *   is dirty (added or deleted) in that scope
   * @throws AclException if validation fails
   */
private static void calculateMasks(List<AclEntry> aclBuilder, EnumMap<AclEntryScope, AclEntry> providedMask, EnumSet<AclEntryScope> maskDirty, EnumSet<AclEntryScope> scopeDirty) throws AclException {
    EnumSet<AclEntryScope> scopeFound = EnumSet.noneOf(AclEntryScope.class);
    EnumMap<AclEntryScope, FsAction> unionPerms = Maps.newEnumMap(AclEntryScope.class);
    EnumSet<AclEntryScope> maskNeeded = EnumSet.noneOf(AclEntryScope.class);
    // union of group class permissions in each scope.
    for (AclEntry entry : aclBuilder) {
        scopeFound.add(entry.getScope());
        if (entry.getType() == GROUP || entry.getName() != null) {
            FsAction scopeUnionPerms = Objects.firstNonNull(unionPerms.get(entry.getScope()), FsAction.NONE);
            unionPerms.put(entry.getScope(), scopeUnionPerms.or(entry.getPermission()));
        }
        if (entry.getName() != null) {
            maskNeeded.add(entry.getScope());
        }
    }
    // Add mask entry if needed in each scope.
    for (AclEntryScope scope : scopeFound) {
        if (!providedMask.containsKey(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.containsKey(scope) && (!scopeDirty.contains(scope) || maskDirty.contains(scope))) {
            // Caller explicitly provided new mask, or we are preserving the existing
            // mask in an unchanged scope.
            aclBuilder.add(providedMask.get(scope));
        } else if (maskNeeded.contains(scope) || providedMask.containsKey(scope)) {
            // Otherwise, if there are maskable entries present, or the ACL
            // previously had a mask, then recalculate a mask automatically.
            aclBuilder.add(new AclEntry.Builder().setScope(scope).setType(MASK).setPermission(unionPerms.get(scope)).build());
        }
    }
}
Also used : FsAction(org.apache.hadoop.fs.permission.FsAction) AclEntryScope(org.apache.hadoop.fs.permission.AclEntryScope) AclEntry(org.apache.hadoop.fs.permission.AclEntry) AclException(org.apache.hadoop.hdfs.protocol.AclException)

Example 14 with FsAction

use of org.apache.hadoop.fs.permission.FsAction in project hadoop by apache.

the class FSPermissionChecker method hasAclPermission.

/**
   * Checks requested access against an Access Control List.  This method relies
   * on finding the ACL data in the relevant portions of {@link FsPermission} and
   * {@link AclFeature} as implemented in the logic of {@link 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
   * {@link 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.
   *
   * @param inode INodeAttributes accessed inode
   * @param snapshotId int snapshot ID
   * @param access FsAction requested permission
   * @param mode FsPermission mode from inode
   * @param aclFeature AclFeature of inode
   * @throws AccessControlException if the ACL denies permission
   */
private boolean hasAclPermission(INodeAttributes inode, FsAction access, FsPermission mode, AclFeature aclFeature) {
    boolean foundMatch = false;
    // Use owner entry from permission bits if user is owner.
    if (getUser().equals(inode.getUserName())) {
        if (mode.getUserAction().implies(access)) {
            return true;
        }
        foundMatch = true;
    }
    // Check named user and group entries if user was not denied by owner entry.
    if (!foundMatch) {
        for (int pos = 0, entry; 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) {
                // matches name.
                if (getUser().equals(name)) {
                    FsAction masked = AclEntryStatusFormat.getPermission(entry).and(mode.getGroupAction());
                    if (masked.implies(access)) {
                        return true;
                    }
                    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 (isMemberOfGroup(group)) {
                    FsAction masked = AclEntryStatusFormat.getPermission(entry).and(mode.getGroupAction());
                    if (masked.implies(access)) {
                        return true;
                    }
                    foundMatch = true;
                }
            }
        }
    }
    // Use other entry if user was not denied by an earlier match.
    return !foundMatch && mode.getOtherAction().implies(access);
}
Also used : FsAction(org.apache.hadoop.fs.permission.FsAction) AclEntryType(org.apache.hadoop.fs.permission.AclEntryType)

Example 15 with FsAction

use of org.apache.hadoop.fs.permission.FsAction in project hadoop by apache.

the class TestSnapshot method genRandomPermission.

/**
   * @return A random FsPermission
   */
private FsPermission genRandomPermission() {
    // randomly select between "rwx" and "rw-"
    FsAction u = random.nextBoolean() ? FsAction.ALL : FsAction.READ_WRITE;
    FsAction g = random.nextBoolean() ? FsAction.ALL : FsAction.READ_WRITE;
    FsAction o = random.nextBoolean() ? FsAction.ALL : FsAction.READ_WRITE;
    return new FsPermission(u, g, o);
}
Also used : FsAction(org.apache.hadoop.fs.permission.FsAction) FsPermission(org.apache.hadoop.fs.permission.FsPermission)

Aggregations

FsAction (org.apache.hadoop.fs.permission.FsAction)16 FsPermission (org.apache.hadoop.fs.permission.FsPermission)8 FileStatus (org.apache.hadoop.fs.FileStatus)4 AclEntry (org.apache.hadoop.fs.permission.AclEntry)3 AclEntryType (org.apache.hadoop.fs.permission.AclEntryType)2 AccessControlException (java.security.AccessControlException)1 Configuration (org.apache.hadoop.conf.Configuration)1 AclEntryScope (org.apache.hadoop.fs.permission.AclEntryScope)1 ScopedAclEntries (org.apache.hadoop.fs.permission.ScopedAclEntries)1 AclException (org.apache.hadoop.hdfs.protocol.AclException)1