Java Code Examples for org.apache.hadoop.fs.permission.AclEntry#getName()

The following examples show how to use org.apache.hadoop.fs.permission.AclEntry#getName() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: FSEditLogOp.java    From big-c with Apache License 2.0 6 votes vote down vote up
private static void write(List<AclEntry> aclEntries, DataOutputStream out)
    throws IOException {
  if (aclEntries == null) {
    out.writeInt(0);
    return;
  }

  out.writeInt(aclEntries.size());
  for (AclEntry e : aclEntries) {
    boolean hasName = e.getName() != null;
    int v = (e.getScope().ordinal() << ACL_EDITLOG_ENTRY_SCOPE_OFFSET)
        | (e.getType().ordinal() << ACL_EDITLOG_ENTRY_TYPE_OFFSET)
        | e.getPermission().ordinal();

    if (hasName) {
      v |= 1 << ACL_EDITLOG_ENTRY_HAS_NAME_OFFSET;
    }
    out.write(v);
    if (hasName) {
      FSImageSerialization.writeString(e.getName(), out);
    }
  }
}
 
Example 2
Source File: TestHDFSIntegration.java    From incubator-sentry with Apache License 2.0 6 votes vote down vote up
private Map<String, FsAction> getAcls(Path path) throws Exception {
  AclStatus aclStatus = miniDFS.getFileSystem().getAclStatus(path);
  Map<String, FsAction> acls = new HashMap<String, FsAction>();
  for (AclEntry ent : aclStatus.getEntries()) {
    if (ent.getType().equals(AclEntryType.GROUP)) {

      // In case of duplicate acl exist, exception should be thrown.
      if (acls.containsKey(ent.getName())) {
        throw new SentryAlreadyExistsException("The acl " + ent.getName() + " already exists.\n");
      } else {
        acls.put(ent.getName(), ent.getPermission());
      }
    }
  }
  return acls;
}
 
Example 3
Source File: SentryAuthorizationProvider.java    From incubator-sentry with Apache License 2.0 6 votes vote down vote up
private void addToACLMap(Map<String, AclEntry> map,
    Collection<AclEntry> entries) {
  for (AclEntry ent : entries) {
    String key = (ent.getName() == null ? "" : ent.getName())
        + ent.getScope() + ent.getType();
    AclEntry aclEntry = map.get(key);
    if (aclEntry == null) {
      map.put(key, ent);
    } else {
      map.put(key,
          new AclEntry.Builder().
          setName(ent.getName()).
          setScope(ent.getScope()).
          setType(ent.getType()).
          setPermission(ent.getPermission().or(aclEntry.getPermission())).
          build());
    }
  }
}
 
Example 4
Source File: TestSnapshotScannerHDFSAclController.java    From hbase with Apache License 2.0 6 votes vote down vote up
static void checkUserAclEntry(FileSystem fs, Path path, String userName, boolean requireAccessAcl,
    boolean requireDefaultAcl) throws IOException {
  boolean accessAclEntry = false;
  boolean defaultAclEntry = false;
  if (fs.exists(path)) {
    for (AclEntry aclEntry : fs.getAclStatus(path).getEntries()) {
      String user = aclEntry.getName();
      if (user != null && user.equals(userName)) {
        if (aclEntry.getScope() == AclEntryScope.DEFAULT) {
          defaultAclEntry = true;
        } else if (aclEntry.getScope() == AclEntryScope.ACCESS) {
          accessAclEntry = true;
        }
      }
    }
  }
  String message = "require user: " + userName + ", path: " + path.toString() + " acl";
  assertEquals(message, requireAccessAcl, accessAclEntry);
  assertEquals(message, requireDefaultAcl, defaultAclEntry);
}
 
Example 5
Source File: AclCommands.java    From big-c with Apache License 2.0 6 votes vote down vote up
/**
 * Prints a single extended ACL entry.  If the mask restricts the
 * permissions of the entry, then also prints the restricted version as the
 * effective permissions.  The mask applies to all named entries and also
 * the unnamed group entry.
 * @param aclStatus AclStatus for the path
 * @param fsPerm FsPermission for the path
 * @param entry AclEntry extended ACL entry to print
 */
private void printExtendedAclEntry(AclStatus aclStatus,
    FsPermission fsPerm, AclEntry entry) {
  if (entry.getName() != null || entry.getType() == AclEntryType.GROUP) {
    FsAction entryPerm = entry.getPermission();
    FsAction effectivePerm = aclStatus
        .getEffectivePermission(entry, fsPerm);
    if (entryPerm != effectivePerm) {
      out.println(String.format("%s\t#effective:%s", entry,
        effectivePerm.SYMBOL));
    } else {
      out.println(entry);
    }
  } else {
    out.println(entry);
  }
}
 
Example 6
Source File: AclCommands.java    From hadoop with Apache License 2.0 6 votes vote down vote up
/**
 * Prints a single extended ACL entry.  If the mask restricts the
 * permissions of the entry, then also prints the restricted version as the
 * effective permissions.  The mask applies to all named entries and also
 * the unnamed group entry.
 * @param aclStatus AclStatus for the path
 * @param fsPerm FsPermission for the path
 * @param entry AclEntry extended ACL entry to print
 */
private void printExtendedAclEntry(AclStatus aclStatus,
    FsPermission fsPerm, AclEntry entry) {
  if (entry.getName() != null || entry.getType() == AclEntryType.GROUP) {
    FsAction entryPerm = entry.getPermission();
    FsAction effectivePerm = aclStatus
        .getEffectivePermission(entry, fsPerm);
    if (entryPerm != effectivePerm) {
      out.println(String.format("%s\t#effective:%s", entry,
        effectivePerm.SYMBOL));
    } else {
      out.println(entry);
    }
  } else {
    out.println(entry);
  }
}
 
Example 7
Source File: FSEditLogOp.java    From hadoop with Apache License 2.0 6 votes vote down vote up
private static void write(List<AclEntry> aclEntries, DataOutputStream out)
    throws IOException {
  if (aclEntries == null) {
    out.writeInt(0);
    return;
  }

  out.writeInt(aclEntries.size());
  for (AclEntry e : aclEntries) {
    boolean hasName = e.getName() != null;
    int v = (e.getScope().ordinal() << ACL_EDITLOG_ENTRY_SCOPE_OFFSET)
        | (e.getType().ordinal() << ACL_EDITLOG_ENTRY_TYPE_OFFSET)
        | e.getPermission().ordinal();

    if (hasName) {
      v |= 1 << ACL_EDITLOG_ENTRY_HAS_NAME_OFFSET;
    }
    out.write(v);
    if (hasName) {
      FSImageSerialization.writeString(e.getName(), out);
    }
  }
}
 
Example 8
Source File: PBHelper.java    From hadoop with Apache License 2.0 5 votes vote down vote up
public static List<AclEntryProto> convertAclEntryProto(
    List<AclEntry> aclSpec) {
  ArrayList<AclEntryProto> r = Lists.newArrayListWithCapacity(aclSpec.size());
  for (AclEntry e : aclSpec) {
    AclEntryProto.Builder builder = AclEntryProto.newBuilder();
    builder.setType(convert(e.getType()));
    builder.setScope(convert(e.getScope()));
    builder.setPermissions(convert(e.getPermission()));
    if (e.getName() != null) {
      builder.setName(e.getName());
    }
    r.add(builder.build());
  }
  return r;
}
 
Example 9
Source File: FSEditLogOp.java    From big-c with Apache License 2.0 5 votes vote down vote up
private static void appendAclEntriesToXml(ContentHandler contentHandler,
    List<AclEntry> aclEntries) throws SAXException {
  for (AclEntry e : aclEntries) {
    contentHandler.startElement("", "", "ENTRY", new AttributesImpl());
    XMLUtils.addSaxString(contentHandler, "SCOPE", e.getScope().name());
    XMLUtils.addSaxString(contentHandler, "TYPE", e.getType().name());
    if (e.getName() != null) {
      XMLUtils.addSaxString(contentHandler, "NAME", e.getName());
    }
    fsActionToXml(contentHandler, e.getPermission());
    contentHandler.endElement("", "", "ENTRY");
  }
}
 
Example 10
Source File: PBHelper.java    From big-c with Apache License 2.0 5 votes vote down vote up
public static List<AclEntryProto> convertAclEntryProto(
    List<AclEntry> aclSpec) {
  ArrayList<AclEntryProto> r = Lists.newArrayListWithCapacity(aclSpec.size());
  for (AclEntry e : aclSpec) {
    AclEntryProto.Builder builder = AclEntryProto.newBuilder();
    builder.setType(convert(e.getType()));
    builder.setScope(convert(e.getScope()));
    builder.setPermissions(convert(e.getPermission()));
    if (e.getName() != null) {
      builder.setName(e.getName());
    }
    r.add(builder.build());
  }
  return r;
}
 
Example 11
Source File: FSEditLogOp.java    From hadoop with Apache License 2.0 5 votes vote down vote up
private static void appendAclEntriesToXml(ContentHandler contentHandler,
    List<AclEntry> aclEntries) throws SAXException {
  for (AclEntry e : aclEntries) {
    contentHandler.startElement("", "", "ENTRY", new AttributesImpl());
    XMLUtils.addSaxString(contentHandler, "SCOPE", e.getScope().name());
    XMLUtils.addSaxString(contentHandler, "TYPE", e.getType().name());
    if (e.getName() != null) {
      XMLUtils.addSaxString(contentHandler, "NAME", e.getName());
    }
    fsActionToXml(contentHandler, e.getPermission());
    contentHandler.endElement("", "", "ENTRY");
  }
}
 
Example 12
Source File: AclStorage.java    From big-c with Apache License 2.0 4 votes vote down vote up
/**
 * 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 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.
  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;
  }

  // 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);
}
 
Example 13
Source File: AclStorage.java    From hadoop with Apache License 2.0 4 votes vote down vote up
/**
 * 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 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.
  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;
  }

  // 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);
}
 
Example 14
Source File: AclTransformation.java    From big-c with Apache License 2.0 4 votes vote down vote up
/**
 * Builds the final list of ACL entries to return by trimming, sorting and
 * validating the ACL entries that have been added.
 *
 * @param aclBuilder ArrayList<AclEntry> containing entries to build
 * @return List<AclEntry> unmodifiable, sorted list of ACL entries
 * @throws AclException if validation fails
 */
private static List<AclEntry> buildAndValidateAcl(
    ArrayList<AclEntry> aclBuilder) throws AclException {
  if (aclBuilder.size() > MAX_ENTRIES) {
    throw new AclException("Invalid ACL: ACL has " + aclBuilder.size() +
      " entries, which exceeds maximum of " + MAX_ENTRIES + ".");
  }
  aclBuilder.trimToSize();
  Collections.sort(aclBuilder, ACL_ENTRY_COMPARATOR);
  // Full iteration to check for duplicates and invalid named entries.
  AclEntry prevEntry = null;
  for (AclEntry entry: aclBuilder) {
    if (prevEntry != null &&
        ACL_ENTRY_COMPARATOR.compare(prevEntry, entry) == 0) {
      throw new AclException(
        "Invalid ACL: multiple entries with same scope, type and name.");
    }
    if (entry.getName() != null && (entry.getType() == MASK ||
        entry.getType() == OTHER)) {
      throw new AclException(
        "Invalid ACL: this entry type must not have a name: " + entry + ".");
    }
    prevEntry = entry;
  }
  // Search for the required base access entries.  If there is a default ACL,
  // then do the same check on the default entries.
  ScopedAclEntries scopedEntries = new ScopedAclEntries(aclBuilder);
  for (AclEntryType type: EnumSet.of(USER, GROUP, OTHER)) {
    AclEntry accessEntryKey = new AclEntry.Builder().setScope(ACCESS)
      .setType(type).build();
    if (Collections.binarySearch(scopedEntries.getAccessEntries(),
        accessEntryKey, ACL_ENTRY_COMPARATOR) < 0) {
      throw new AclException(
        "Invalid ACL: the user, group and other entries are required.");
    }
    if (!scopedEntries.getDefaultEntries().isEmpty()) {
      AclEntry defaultEntryKey = new AclEntry.Builder().setScope(DEFAULT)
        .setType(type).build();
      if (Collections.binarySearch(scopedEntries.getDefaultEntries(),
          defaultEntryKey, ACL_ENTRY_COMPARATOR) < 0) {
        throw new AclException(
          "Invalid default ACL: the user, group and other entries are required.");
      }
    }
  }
  return Collections.unmodifiableList(aclBuilder);
}
 
Example 15
Source File: AclTransformation.java    From big-c with Apache License 2.0 4 votes vote down vote up
/**
 * 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);
  // Determine which scopes are present, which scopes need a mask, and the
  // 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());
    }
  }
}
 
Example 16
Source File: AclTransformation.java    From hadoop with Apache License 2.0 4 votes vote down vote up
/**
 * 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);
  // Determine which scopes are present, which scopes need a mask, and the
  // 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());
    }
  }
}
 
Example 17
Source File: AclTransformation.java    From hadoop with Apache License 2.0 4 votes vote down vote up
/**
 * Builds the final list of ACL entries to return by trimming, sorting and
 * validating the ACL entries that have been added.
 *
 * @param aclBuilder ArrayList<AclEntry> containing entries to build
 * @return List<AclEntry> unmodifiable, sorted list of ACL entries
 * @throws AclException if validation fails
 */
private static List<AclEntry> buildAndValidateAcl(
    ArrayList<AclEntry> aclBuilder) throws AclException {
  if (aclBuilder.size() > MAX_ENTRIES) {
    throw new AclException("Invalid ACL: ACL has " + aclBuilder.size() +
      " entries, which exceeds maximum of " + MAX_ENTRIES + ".");
  }
  aclBuilder.trimToSize();
  Collections.sort(aclBuilder, ACL_ENTRY_COMPARATOR);
  // Full iteration to check for duplicates and invalid named entries.
  AclEntry prevEntry = null;
  for (AclEntry entry: aclBuilder) {
    if (prevEntry != null &&
        ACL_ENTRY_COMPARATOR.compare(prevEntry, entry) == 0) {
      throw new AclException(
        "Invalid ACL: multiple entries with same scope, type and name.");
    }
    if (entry.getName() != null && (entry.getType() == MASK ||
        entry.getType() == OTHER)) {
      throw new AclException(
        "Invalid ACL: this entry type must not have a name: " + entry + ".");
    }
    prevEntry = entry;
  }
  // Search for the required base access entries.  If there is a default ACL,
  // then do the same check on the default entries.
  ScopedAclEntries scopedEntries = new ScopedAclEntries(aclBuilder);
  for (AclEntryType type: EnumSet.of(USER, GROUP, OTHER)) {
    AclEntry accessEntryKey = new AclEntry.Builder().setScope(ACCESS)
      .setType(type).build();
    if (Collections.binarySearch(scopedEntries.getAccessEntries(),
        accessEntryKey, ACL_ENTRY_COMPARATOR) < 0) {
      throw new AclException(
        "Invalid ACL: the user, group and other entries are required.");
    }
    if (!scopedEntries.getDefaultEntries().isEmpty()) {
      AclEntry defaultEntryKey = new AclEntry.Builder().setScope(DEFAULT)
        .setType(type).build();
      if (Collections.binarySearch(scopedEntries.getDefaultEntries(),
          defaultEntryKey, ACL_ENTRY_COMPARATOR) < 0) {
        throw new AclException(
          "Invalid default ACL: the user, group and other entries are required.");
      }
    }
  }
  return Collections.unmodifiableList(aclBuilder);
}