From ef1cc725b8c1301f33bcb80b63b12d45dc23bed8 Mon Sep 17 00:00:00 2001 From: Ajay Yadav <7813154+ajayydv@users.noreply.github.com> Date: Tue, 21 May 2019 15:53:40 -0700 Subject: [PATCH] HDDS-1538. Update ozone protobuf message for ACLs. Contributed by Ajay Kumar. (#828) --- .../org/apache/hadoop/ozone/OzoneConsts.java | 3 +- .../src/main/resources/ozone-default.xml | 18 +-- .../hadoop/ozone/client/rest/RestClient.java | 6 +- .../hadoop/ozone/client/rpc/RpcClient.java | 25 ++-- .../org/apache/hadoop/ozone/OzoneAcl.java | 112 +++++++----------- .../apache/hadoop/ozone/om/OMConfigKeys.java | 12 -- .../ozone/om/helpers/OmOzoneAclMap.java | 60 +++++++--- .../hadoop/ozone/protocolPB/OMPBHelper.java | 67 ++++++----- .../ozone/security/acl/IAccessAuthorizer.java | 20 +++- .../ozone/security/acl/OzoneAclConfig.java | 65 ++++++++++ .../src/main/proto/OzoneManagerProtocol.proto | 17 ++- .../apache/hadoop/ozone/TestOzoneAcls.java | 79 ++++++++---- .../rpc/TestOzoneRpcClientAbstract.java | 20 ++-- .../hadoop/ozone/om/TestOzoneManager.java | 21 ++-- .../hadoop/ozone/ozShell/TestOzoneShell.java | 13 +- .../storage/DistributedStorageHandler.java | 21 ++-- .../hadoop/ozone/om/VolumeManagerImpl.java | 4 +- .../ozone/om/TestBucketManagerImpl.java | 18 +-- .../apache/hadoop/ozone/scm/cli/SQLCLI.java | 2 +- 19 files changed, 339 insertions(+), 244 deletions(-) rename {hadoop-hdds => hadoop-ozone}/common/src/main/java/org/apache/hadoop/ozone/OzoneAcl.java (63%) create mode 100644 hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/OzoneAclConfig.java rename {hadoop-hdds => hadoop-ozone}/common/src/test/java/org/apache/hadoop/ozone/TestOzoneAcls.java (57%) diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java index ce1e97e34d..4f249f854b 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java @@ -52,12 +52,11 @@ public final class OzoneConsts { public static final String OZONE_ACL_USER_TYPE = "user"; public static final String OZONE_ACL_GROUP_TYPE = "group"; public static final String OZONE_ACL_WORLD_TYPE = "world"; + public static final String OZONE_ACL_ANONYMOUS_TYPE = "anonymous"; public static final String OZONE_ACL_IP_TYPE = "ip"; public static final String OZONE_ACL_READ = "r"; public static final String OZONE_ACL_WRITE = "w"; - public static final String OZONE_ACL_READ_WRITE = "rw"; - public static final String OZONE_ACL_WRITE_READ = "wr"; public static final String OZONE_ACL_DELETE = "d"; public static final String OZONE_ACL_LIST = "l"; public static final String OZONE_ACL_ALL = "a"; diff --git a/hadoop-hdds/common/src/main/resources/ozone-default.xml b/hadoop-hdds/common/src/main/resources/ozone-default.xml index a46ddb16a8..305cac5a2c 100644 --- a/hadoop-hdds/common/src/main/resources/ozone-default.xml +++ b/hadoop-hdds/common/src/main/resources/ozone-default.xml @@ -540,14 +540,6 @@ the address of the OM. - - ozone.om.group.rights - READ_WRITE - OM, SECURITY - - Default group permissions in Ozone OM. - - ozone.om.handler.count.key 20 @@ -640,14 +632,6 @@ of buckets or keys inside each bucket a user can create. - - ozone.om.user.rights - READ_WRITE - OM, SECURITY - - Default user permissions used in OM. - - ozone.om.db.dirs @@ -1809,7 +1793,7 @@ assumed. - + hdds.block.token.enabled false diff --git a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rest/RestClient.java b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rest/RestClient.java index 2f37713159..71fb8ca8c6 100644 --- a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rest/RestClient.java +++ b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rest/RestClient.java @@ -112,7 +112,7 @@ public class RestClient implements ClientProtocol { private final URI ozoneRestUri; private final CloseableHttpClient httpClient; private final UserGroupInformation ugi; - private final OzoneAcl.OzoneACLRights userRights; + // private final OzoneAcl.OzoneACLRights userRights; /** * Creates RestClient instance with the given configuration. @@ -161,8 +161,8 @@ public RestClient(Configuration conf) .build()) .build(); - this.userRights = conf.getEnum(OMConfigKeys.OZONE_OM_USER_RIGHTS, - OMConfigKeys.OZONE_OM_USER_RIGHTS_DEFAULT); +// this.userRights = conf.getEnum(OMConfigKeys.OZONE_OM_USER_RIGHTS, +// OMConfigKeys.OZONE_OM_USER_RIGHTS_DEFAULT); // TODO: Add new configuration parameter to configure RestServerSelector. RestServerSelector defaultSelector = new DefaultRestServerSelector(); diff --git a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java index ab40c5231a..3aa4fb8e63 100644 --- a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java +++ b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java @@ -73,7 +73,6 @@ .OzoneManagerProtocolClientSideTranslatorPB; import org.apache.hadoop.net.NetUtils; import org.apache.hadoop.ozone.OzoneAcl; -import org.apache.hadoop.ozone.om.OMConfigKeys; import org.apache.hadoop.ozone.protocol.proto .OzoneManagerProtocolProtos.ServicePort; import org.apache.hadoop.hdds.protocol.proto.HddsProtos; @@ -85,6 +84,9 @@ import org.apache.hadoop.hdds.scm.protocolPB .StorageContainerLocationProtocolPB; import org.apache.hadoop.ozone.security.OzoneTokenIdentifier; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLIdentityType; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType; +import org.apache.hadoop.ozone.security.acl.OzoneAclConfig; import org.apache.hadoop.ozone.web.utils.OzoneUtils; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.token.Token; @@ -121,8 +123,8 @@ public class RpcClient implements ClientProtocol, KeyProviderTokenIssuer { private final int bytesPerChecksum; private boolean verifyChecksum; private final UserGroupInformation ugi; - private final OzoneAcl.OzoneACLRights userRights; - private final OzoneAcl.OzoneACLRights groupRights; + private final ACLType userRights; + private final ACLType groupRights; private final long streamBufferFlushSize; private final long streamBufferMaxSize; private final long blockSize; @@ -141,10 +143,11 @@ public RpcClient(Configuration conf) throws IOException { Preconditions.checkNotNull(conf); this.conf = new OzoneConfiguration(conf); this.ugi = UserGroupInformation.getCurrentUser(); - this.userRights = conf.getEnum(OMConfigKeys.OZONE_OM_USER_RIGHTS, - OMConfigKeys.OZONE_OM_USER_RIGHTS_DEFAULT); - this.groupRights = conf.getEnum(OMConfigKeys.OZONE_OM_GROUP_RIGHTS, - OMConfigKeys.OZONE_OM_GROUP_RIGHTS_DEFAULT); + // Get default acl rights for user and group. + OzoneAclConfig aclConfig = this.conf.getObject(OzoneAclConfig.class); + this.userRights = aclConfig.getUserDefaultRights(); + this.groupRights = aclConfig.getGroupDefaultRights(); + this.ozoneManagerClient = new OzoneManagerProtocolClientSideTranslatorPB( this.conf, clientId.toString(), ugi); long scmVersion = @@ -256,13 +259,13 @@ public void createVolume(String volumeName, VolumeArgs volArgs) OzoneQuota.parseQuota(volArgs.getQuota()).sizeInBytes(); List listOfAcls = new ArrayList<>(); //User ACL - listOfAcls.add(new OzoneAcl(OzoneAcl.OzoneACLType.USER, + listOfAcls.add(new OzoneAcl(ACLIdentityType.USER, owner, userRights)); //Group ACLs of the User List userGroups = Arrays.asList(UserGroupInformation .createRemoteUser(owner).getGroupNames()); userGroups.stream().forEach((group) -> listOfAcls.add( - new OzoneAcl(OzoneAcl.OzoneACLType.GROUP, group, groupRights))); + new OzoneAcl(ACLIdentityType.GROUP, group, groupRights))); //ACLs from VolumeArgs if(volArgs.getAcls() != null) { listOfAcls.addAll(volArgs.getAcls()); @@ -403,13 +406,13 @@ public void createBucket( List listOfAcls = new ArrayList<>(); //User ACL - listOfAcls.add(new OzoneAcl(OzoneAcl.OzoneACLType.USER, + listOfAcls.add(new OzoneAcl(ACLIdentityType.USER, ugi.getUserName(), userRights)); //Group ACLs of the User List userGroups = Arrays.asList(UserGroupInformation .createRemoteUser(ugi.getUserName()).getGroupNames()); userGroups.stream().forEach((group) -> listOfAcls.add( - new OzoneAcl(OzoneAcl.OzoneACLType.GROUP, group, groupRights))); + new OzoneAcl(ACLIdentityType.GROUP, group, groupRights))); //ACLs from BucketArgs if(bucketArgs.getAcls() != null) { listOfAcls.addAll(bucketArgs.getAcls()); diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneAcl.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OzoneAcl.java similarity index 63% rename from hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneAcl.java rename to hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OzoneAcl.java index 1827b23bf1..eaec507314 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneAcl.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OzoneAcl.java @@ -19,6 +19,11 @@ package org.apache.hadoop.ozone; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLIdentityType; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType; + +import java.util.ArrayList; +import java.util.List; import java.util.Objects; /** @@ -32,9 +37,9 @@ * */ public class OzoneAcl { - private OzoneACLType type; + private ACLIdentityType type; private String name; - private OzoneACLRights rights; + private List rights; /** * Constructor for OzoneAcl. @@ -47,16 +52,37 @@ public OzoneAcl() { * * @param type - Type * @param name - Name of user - * @param rights - Rights + * @param acl - Rights */ - public OzoneAcl(OzoneACLType type, String name, OzoneACLRights rights) { + public OzoneAcl(ACLIdentityType type, String name, ACLType acl) { this.name = name; - this.rights = rights; + this.rights = new ArrayList<>(); + this.rights.add(acl); this.type = type; - if (type == OzoneACLType.WORLD && name.length() != 0) { + if (type == ACLIdentityType.WORLD && name.length() != 0) { throw new IllegalArgumentException("Unexpected name part in world type"); } - if (((type == OzoneACLType.USER) || (type == OzoneACLType.GROUP)) + if (((type == ACLIdentityType.USER) || (type == ACLIdentityType.GROUP)) + && (name.length() == 0)) { + throw new IllegalArgumentException("User or group name is required"); + } + } + + /** + * Constructor for OzoneAcl. + * + * @param type - Type + * @param name - Name of user + * @param acls - Rights + */ + public OzoneAcl(ACLIdentityType type, String name, List acls) { + this.name = name; + this.rights = acls; + this.type = type; + if (type == ACLIdentityType.WORLD && name.length() != 0) { + throw new IllegalArgumentException("Unexpected name part in world type"); + } + if (((type == ACLIdentityType.USER) || (type == ACLIdentityType.GROUP)) && (name.length() == 0)) { throw new IllegalArgumentException("User or group name is required"); } @@ -78,17 +104,20 @@ public static OzoneAcl parseAcl(String acl) throws IllegalArgumentException { throw new IllegalArgumentException("ACLs are not in expected format"); } - OzoneACLType aclType = OzoneACLType.valueOf(parts[0].toUpperCase()); - OzoneACLRights rights = OzoneACLRights.getACLRight(parts[2].toLowerCase()); + ACLIdentityType aclType = ACLIdentityType.valueOf(parts[0].toUpperCase()); + List acls = new ArrayList<>(); + for (char ch : parts[2].toCharArray()) { + acls.add(ACLType.getACLRight(String.valueOf(ch))); + } // TODO : Support sanitation of these user names by calling into // userAuth Interface. - return new OzoneAcl(aclType, parts[1], rights); + return new OzoneAcl(aclType, parts[1], acls); } @Override public String toString() { - return type + ":" + name + ":" + OzoneACLRights.getACLRightsString(rights); + return type + ":" + name + ":" + ACLType.getACLString(rights); } /** @@ -120,7 +149,7 @@ public String getName() { * * @return - Rights */ - public OzoneACLRights getRights() { + public List getRights() { return rights; } @@ -129,7 +158,7 @@ public OzoneACLRights getRights() { * * @return type */ - public OzoneACLType getType() { + public ACLIdentityType getType() { return type; } @@ -150,9 +179,7 @@ public boolean equals(Object obj) { return false; } OzoneAcl otherAcl = (OzoneAcl) obj; - return otherAcl.getName().equals(this.getName()) && - otherAcl.getRights() == this.getRights() && - otherAcl.getType() == this.getType(); + return otherAcl.toString().equals(this.toString()); } /** @@ -177,57 +204,4 @@ public enum OzoneACLType { value = val; } } - - /** - * ACL rights. - */ - public enum OzoneACLRights { - READ, WRITE, READ_WRITE; - - /** - * Returns the ACL rights based on passed in String. - * - * @param type ACL right string - * - * @return OzoneACLRights - */ - public static OzoneACLRights getACLRight(String type) { - if (type == null || type.isEmpty()) { - throw new IllegalArgumentException("ACL right cannot be empty"); - } - - switch (type) { - case OzoneConsts.OZONE_ACL_READ: - return OzoneACLRights.READ; - case OzoneConsts.OZONE_ACL_WRITE: - return OzoneACLRights.WRITE; - case OzoneConsts.OZONE_ACL_READ_WRITE: - case OzoneConsts.OZONE_ACL_WRITE_READ: - return OzoneACLRights.READ_WRITE; - default: - throw new IllegalArgumentException("ACL right is not recognized"); - } - - } - - /** - * Returns String representation of ACL rights. - * @param acl OzoneACLRights - * @return String representation of acl - */ - public static String getACLRightsString(OzoneACLRights acl) { - switch(acl) { - case READ: - return OzoneConsts.OZONE_ACL_READ; - case WRITE: - return OzoneConsts.OZONE_ACL_WRITE; - case READ_WRITE: - return OzoneConsts.OZONE_ACL_READ_WRITE; - default: - throw new IllegalArgumentException("ACL right is not recognized"); - } - } - - } - } diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/OMConfigKeys.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/OMConfigKeys.java index 60dde44119..5f1f579f6d 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/OMConfigKeys.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/OMConfigKeys.java @@ -19,7 +19,6 @@ import java.util.concurrent.TimeUnit; -import org.apache.hadoop.ozone.OzoneAcl; import org.apache.ratis.util.TimeDuration; /** @@ -78,17 +77,6 @@ private OMConfigKeys() { "ozone.om.user.max.volume"; public static final int OZONE_OM_USER_MAX_VOLUME_DEFAULT = 1024; - // OM Default user/group permissions - public static final String OZONE_OM_USER_RIGHTS = - "ozone.om.user.rights"; - public static final OzoneAcl.OzoneACLRights OZONE_OM_USER_RIGHTS_DEFAULT = - OzoneAcl.OzoneACLRights.READ_WRITE; - - public static final String OZONE_OM_GROUP_RIGHTS = - "ozone.om.group.rights"; - public static final OzoneAcl.OzoneACLRights OZONE_OM_GROUP_RIGHTS_DEFAULT = - OzoneAcl.OzoneACLRights.READ_WRITE; - public static final String OZONE_KEY_DELETING_LIMIT_PER_TASK = "ozone.key.deleting.limit.per.task"; public static final int OZONE_KEY_DELETING_LIMIT_PER_TASK_DEFAULT = 1000; diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmOzoneAclMap.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmOzoneAclMap.java index 2584eb58c2..8831c6b879 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmOzoneAclMap.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmOzoneAclMap.java @@ -37,7 +37,7 @@ @SuppressWarnings("ProtocolBufferOrdinal") public class OmOzoneAclMap { // per Acl Type user:rights map - private ArrayList> aclMaps; + private ArrayList>> aclMaps; OmOzoneAclMap() { aclMaps = new ArrayList<>(); @@ -46,51 +46,75 @@ public class OmOzoneAclMap { } } - private Map getMap(OzoneAclType type) { + private Map> getMap(OzoneAclType type) { return aclMaps.get(type.ordinal()); } // For a given acl type and user, get the stored acl - private OzoneAclRights getAcl(OzoneAclType type, String user) { + private List getAcl(OzoneAclType type, String user) { return getMap(type).get(user); } // Add a new acl to the map public void addAcl(OzoneAclInfo acl) { - getMap(acl.getType()).put(acl.getName(), acl.getRights()); + getMap(acl.getType()).put(acl.getName(), acl.getRightsList()); } // for a given acl, check if the user has access rights public boolean hasAccess(OzoneAclInfo acl) { - OzoneAclRights storedRights = getAcl(acl.getType(), acl.getName()); - if (storedRights != null) { - switch (acl.getRights()) { - case READ: - return (storedRights == OzoneAclRights.READ) - || (storedRights == OzoneAclRights.READ_WRITE); + if (acl == null) { + return false; + } + + List storedRights = getAcl(acl.getType(), acl.getName()); + if(storedRights == null) { + return false; + } + + for (OzoneAclRights right : storedRights) { + switch (right) { + case CREATE: + return (right == OzoneAclRights.CREATE) + || (right == OzoneAclRights.ALL); + case LIST: + return (right == OzoneAclRights.LIST) + || (right == OzoneAclRights.ALL); case WRITE: - return (storedRights == OzoneAclRights.WRITE) - || (storedRights == OzoneAclRights.READ_WRITE); - case READ_WRITE: - return (storedRights == OzoneAclRights.READ_WRITE); + return (right == OzoneAclRights.WRITE) + || (right == OzoneAclRights.ALL); + case READ: + return (right == OzoneAclRights.READ) + || (right == OzoneAclRights.ALL); + case DELETE: + return (right == OzoneAclRights.DELETE) + || (right == OzoneAclRights.ALL); + case READ_ACL: + return (right == OzoneAclRights.READ_ACL) + || (right == OzoneAclRights.ALL); + case WRITE_ACL: + return (right == OzoneAclRights.WRITE_ACL) + || (right == OzoneAclRights.ALL); + case ALL: + return (right == OzoneAclRights.ALL); + case NONE: + return !(right == OzoneAclRights.NONE); default: return false; } - } else { - return false; } + return false; } // Convert this map to OzoneAclInfo Protobuf List public List ozoneAclGetProtobuf() { List aclList = new LinkedList<>(); for (OzoneAclType type: OzoneAclType.values()) { - for (Map.Entry entry : + for (Map.Entry> entry : aclMaps.get(type.ordinal()).entrySet()) { OzoneAclInfo aclInfo = OzoneAclInfo.newBuilder() .setName(entry.getKey()) .setType(type) - .setRights(entry.getValue()) + .addAllRights(entry.getValue()) .build(); aclList.add(aclInfo); } diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/protocolPB/OMPBHelper.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/protocolPB/OMPBHelper.java index fa6fc85b03..45ae0b301a 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/protocolPB/OMPBHelper.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/protocolPB/OMPBHelper.java @@ -41,9 +41,15 @@ import org.apache.hadoop.ozone.protocol.proto .OzoneManagerProtocolProtos.OzoneAclInfo.OzoneAclRights; import org.apache.hadoop.ozone.security.OzoneTokenIdentifier; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLIdentityType; import org.apache.hadoop.security.proto.SecurityProtos.TokenProto; import org.apache.hadoop.security.token.Token; +import java.util.List; +import java.util.ArrayList; + /** * Utilities for converting protobuf classes. */ @@ -59,7 +65,7 @@ private OMPBHelper() { */ public static OzoneAclInfo convertOzoneAcl(OzoneAcl acl) { OzoneAclInfo.OzoneAclType aclType; - switch(acl.getType()) { + switch (acl.getType()) { case USER: aclType = OzoneAclType.USER; break; @@ -69,27 +75,24 @@ public static OzoneAclInfo convertOzoneAcl(OzoneAcl acl) { case WORLD: aclType = OzoneAclType.WORLD; break; + case ANONYMOUS: + aclType = OzoneAclType.ANONYMOUS; + break; + case CLIENT_IP: + aclType = OzoneAclType.CLIENT_IP; + break; default: throw new IllegalArgumentException("ACL type is not recognized"); } - OzoneAclInfo.OzoneAclRights aclRights; - switch(acl.getRights()) { - case READ: - aclRights = OzoneAclRights.READ; - break; - case WRITE: - aclRights = OzoneAclRights.WRITE; - break; - case READ_WRITE: - aclRights = OzoneAclRights.READ_WRITE; - break; - default: - throw new IllegalArgumentException("ACL right is not recognized"); + List aclRights = new ArrayList<>(); + + for (ACLType right : acl.getRights()) { + aclRights.add(OzoneAclRights.valueOf(right.name())); } return OzoneAclInfo.newBuilder().setType(aclType) .setName(acl.getName()) - .setRights(aclRights) + .addAllRights(aclRights) .build(); } @@ -98,35 +101,31 @@ public static OzoneAclInfo convertOzoneAcl(OzoneAcl acl) { * @return OzoneAcl */ public static OzoneAcl convertOzoneAcl(OzoneAclInfo aclInfo) { - OzoneAcl.OzoneACLType aclType; - switch(aclInfo.getType()) { + ACLIdentityType aclType; + switch (aclInfo.getType()) { case USER: - aclType = OzoneAcl.OzoneACLType.USER; + aclType = ACLIdentityType.USER; break; case GROUP: - aclType = OzoneAcl.OzoneACLType.GROUP; + aclType = ACLIdentityType.GROUP; break; case WORLD: - aclType = OzoneAcl.OzoneACLType.WORLD; + aclType = ACLIdentityType.WORLD; + break; + case ANONYMOUS: + aclType = ACLIdentityType.ANONYMOUS; + break; + case CLIENT_IP: + aclType = ACLIdentityType.CLIENT_IP; break; default: throw new IllegalArgumentException("ACL type is not recognized"); } - OzoneAcl.OzoneACLRights aclRights; - switch(aclInfo.getRights()) { - case READ: - aclRights = OzoneAcl.OzoneACLRights.READ; - break; - case WRITE: - aclRights = OzoneAcl.OzoneACLRights.WRITE; - break; - case READ_WRITE: - aclRights = OzoneAcl.OzoneACLRights.READ_WRITE; - break; - default: - throw new IllegalArgumentException("ACL right is not recognized"); - } + List aclRights = new ArrayList<>(); + for (OzoneAclRights acl : aclInfo.getRightsList()) { + aclRights.add(ACLType.valueOf(acl.name())); + } return new OzoneAcl(aclType, aclInfo.getName(), aclRights); } diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/IAccessAuthorizer.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/IAccessAuthorizer.java index 074c07d69b..2c47000a6c 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/IAccessAuthorizer.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/IAccessAuthorizer.java @@ -20,6 +20,8 @@ import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.ozone.OzoneConsts; +import java.util.List; + /** * Public API for Ozone ACLs. Security providers providing support for Ozone * ACLs should implement this. @@ -84,7 +86,8 @@ public static ACLType getACLRight(String type) { case OzoneConsts.OZONE_ACL_NONE: return ACLType.NONE; default: - throw new IllegalArgumentException("ACL right is not recognized"); + throw new IllegalArgumentException(type + " ACL right is not " + + "recognized"); } } @@ -92,10 +95,18 @@ public static ACLType getACLRight(String type) { /** * Returns String representation of ACL rights. * - * @param acl ACLType + * @param acls ACLType * @return String representation of acl */ - public static String getACLRightsString(ACLType acl) { + public static String getACLString(List acls) { + StringBuffer sb = new StringBuffer(); + acls.forEach(acl -> { + sb.append(getAclString(acl)); + }); + return sb.toString(); + } + + public static String getAclString(ACLType acl) { switch (acl) { case READ: return OzoneConsts.OZONE_ACL_READ; @@ -129,7 +140,8 @@ enum ACLIdentityType { USER(OzoneConsts.OZONE_ACL_USER_TYPE), GROUP(OzoneConsts.OZONE_ACL_GROUP_TYPE), CLIENT_IP(OzoneConsts.OZONE_ACL_IP_TYPE), - WORLD(OzoneConsts.OZONE_ACL_WORLD_TYPE); + WORLD(OzoneConsts.OZONE_ACL_WORLD_TYPE), + ANONYMOUS(OzoneConsts.OZONE_ACL_ANONYMOUS_TYPE); @Override public String toString() { diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/OzoneAclConfig.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/OzoneAclConfig.java new file mode 100644 index 0000000000..9641eda18d --- /dev/null +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/OzoneAclConfig.java @@ -0,0 +1,65 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.ozone.security.acl; + +import org.apache.hadoop.hdds.conf.Config; +import org.apache.hadoop.hdds.conf.ConfigGroup; +import org.apache.hadoop.hdds.conf.ConfigTag; +import org.apache.hadoop.hdds.conf.ConfigType; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType; + +/** + * Ozone ACL config pojo. + * */ +@ConfigGroup(prefix = "ozone.om") +public class OzoneAclConfig { + // OM Default user/group permissions + private ACLType userDefaultRights = ACLType.ALL; + private ACLType groupDefaultRights = ACLType.ALL; + + @Config(key = "user.rights", + defaultValue = "ALL", + type = ConfigType.STRING, + tags = {ConfigTag.OM, ConfigTag.SECURITY}, + description = "Default user permissions set for an object in " + + "OzoneManager." + ) + public void setUserDefaultRights(String userRights) { + this.userDefaultRights = ACLType.valueOf(userRights); + } + + @Config(key = "group.rights", + defaultValue = "ALL", + type = ConfigType.STRING, + tags = {ConfigTag.OM, ConfigTag.SECURITY}, + description = "Default group permissions set for an object in " + + "OzoneManager." + ) + public void setGroupDefaultRights(String groupRights) { + this.groupDefaultRights = ACLType.valueOf(groupRights); + } + + public ACLType getUserDefaultRights() { + return userDefaultRights; + } + + public ACLType getGroupDefaultRights() { + return groupDefaultRights; + } + +} diff --git a/hadoop-ozone/common/src/main/proto/OzoneManagerProtocol.proto b/hadoop-ozone/common/src/main/proto/OzoneManagerProtocol.proto index 50751ed2c4..e82741bed5 100644 --- a/hadoop-ozone/common/src/main/proto/OzoneManagerProtocol.proto +++ b/hadoop-ozone/common/src/main/proto/OzoneManagerProtocol.proto @@ -451,15 +451,24 @@ message OzoneAclInfo { USER = 1; GROUP = 2; WORLD = 3; + ANONYMOUS = 4; + CLIENT_IP = 5; } + enum OzoneAclRights { - READ = 1; - WRITE = 2; - READ_WRITE = 3; + CREATE = 1; + LIST = 2; + DELETE = 3; + READ = 4; + WRITE = 5; + READ_ACL = 6; + WRITE_ACL = 7; + ALL = 8; + NONE = 9; } required OzoneAclType type = 1; required string name = 2; - required OzoneAclRights rights = 3; + repeated OzoneAclRights rights = 3; } message CreateBucketRequest { diff --git a/hadoop-hdds/common/src/test/java/org/apache/hadoop/ozone/TestOzoneAcls.java b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/TestOzoneAcls.java similarity index 57% rename from hadoop-hdds/common/src/test/java/org/apache/hadoop/ozone/TestOzoneAcls.java rename to hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/TestOzoneAcls.java index 03c45c5019..2cd3d9ec98 100644 --- a/hadoop-hdds/common/src/test/java/org/apache/hadoop/ozone/TestOzoneAcls.java +++ b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/TestOzoneAcls.java @@ -18,16 +18,20 @@ package org.apache.hadoop.ozone; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLIdentityType; + import org.junit.Test; +import java.util.Arrays; import java.util.HashMap; import java.util.Set; +import static org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; /** - * This class is to test acl stoarge and retreival in ozone store. + * This class is to test acl storage and retrieval in ozone store. */ public class TestOzoneAcls { @@ -39,8 +43,8 @@ public void testAclParse() { testMatrix.put("user:bilbo:r", Boolean.TRUE); testMatrix.put("user:bilbo:w", Boolean.TRUE); testMatrix.put("user:bilbo:rw", Boolean.TRUE); - testMatrix.put("user:bilbo:wr", Boolean.TRUE); - testMatrix.put(" user:bilbo:wr ", Boolean.TRUE); + testMatrix.put("user:bilbo:a", Boolean.TRUE); + testMatrix.put(" user:bilbo:a ", Boolean.TRUE); // ACLs makes no judgement on the quality of @@ -53,7 +57,16 @@ public void testAclParse() { testMatrix.put("", Boolean.FALSE); testMatrix.put(null, Boolean.FALSE); testMatrix.put(" user:bilbo:", Boolean.FALSE); - testMatrix.put(" user:bilbo:rx", Boolean.FALSE); + testMatrix.put(" user:bilbo:rx", Boolean.TRUE); + testMatrix.put(" user:bilbo:rwdlncxy", Boolean.TRUE); + testMatrix.put(" group:bilbo:rwdlncxy", Boolean.TRUE); + testMatrix.put(" world::rwdlncxy", Boolean.TRUE); + testMatrix.put(" user:bilbo:rncxy", Boolean.TRUE); + testMatrix.put(" group:bilbo:ncxy", Boolean.TRUE); + testMatrix.put(" world::ncxy", Boolean.TRUE); + testMatrix.put(" user:bilbo:rwcxy", Boolean.TRUE); + testMatrix.put(" group:bilbo:rwcxy", Boolean.TRUE); + testMatrix.put(" world::rwcxy", Boolean.TRUE); testMatrix.put(" user:bilbo:mk", Boolean.FALSE); testMatrix.put(" user::rw", Boolean.FALSE); testMatrix.put("user11:bilbo:rw", Boolean.FALSE); @@ -62,12 +75,12 @@ public void testAclParse() { testMatrix.put(" group:hobbit:r", Boolean.TRUE); testMatrix.put(" group:hobbit:w", Boolean.TRUE); testMatrix.put(" group:hobbit:rw", Boolean.TRUE); - testMatrix.put(" group:hobbit:wr", Boolean.TRUE); + testMatrix.put(" group:hobbit:a", Boolean.TRUE); testMatrix.put(" group:*:rw", Boolean.TRUE); testMatrix.put(" group:~!:rw", Boolean.TRUE); testMatrix.put(" group:hobbit:", Boolean.FALSE); - testMatrix.put(" group:hobbit:rx", Boolean.FALSE); + testMatrix.put(" group:hobbit:rx", Boolean.TRUE); testMatrix.put(" group:hobbit:mk", Boolean.FALSE); testMatrix.put(" group::", Boolean.FALSE); testMatrix.put(" group::rw", Boolean.FALSE); @@ -77,14 +90,14 @@ public void testAclParse() { testMatrix.put("JUNK group:hobbit:r", Boolean.FALSE); testMatrix.put("JUNK group:hobbit:w", Boolean.FALSE); testMatrix.put("JUNK group:hobbit:rw", Boolean.FALSE); - testMatrix.put("JUNK group:hobbit:wr", Boolean.FALSE); + testMatrix.put("JUNK group:hobbit:a", Boolean.FALSE); testMatrix.put("JUNK group:*:rw", Boolean.FALSE); testMatrix.put("JUNK group:~!:rw", Boolean.FALSE); testMatrix.put(" world::r", Boolean.TRUE); testMatrix.put(" world::w", Boolean.TRUE); testMatrix.put(" world::rw", Boolean.TRUE); - testMatrix.put(" world::wr", Boolean.TRUE); + testMatrix.put(" world::a", Boolean.TRUE); testMatrix.put(" world:bilbo:w", Boolean.FALSE); testMatrix.put(" world:bilbo:rw", Boolean.FALSE); @@ -97,7 +110,7 @@ public void testAclParse() { try { OzoneAcl.parseAcl(key); // should never get here since parseAcl will throw - fail("An exception was expected but did not happen."); + fail("An exception was expected but did not happen. Key: " + key); } catch (IllegalArgumentException e) { // nothing to do } @@ -109,33 +122,51 @@ public void testAclParse() { public void testAclValues() { OzoneAcl acl = OzoneAcl.parseAcl("user:bilbo:rw"); assertEquals(acl.getName(), "bilbo"); - assertEquals(OzoneAcl.OzoneACLRights.READ_WRITE, acl.getRights()); - assertEquals(OzoneAcl.OzoneACLType.USER, acl.getType()); + assertEquals(Arrays.asList(READ, WRITE), acl.getRights()); + assertEquals(ACLIdentityType.USER, acl.getType()); - acl = OzoneAcl.parseAcl("user:bilbo:wr"); + acl = OzoneAcl.parseAcl("user:bilbo:a"); assertEquals("bilbo", acl.getName()); - assertEquals(OzoneAcl.OzoneACLRights.READ_WRITE, acl.getRights()); - assertEquals(OzoneAcl.OzoneACLType.USER, acl.getType()); + assertEquals(Arrays.asList(ALL), acl.getRights()); + assertEquals(ACLIdentityType.USER, acl.getType()); acl = OzoneAcl.parseAcl("user:bilbo:r"); assertEquals("bilbo", acl.getName()); - assertEquals(OzoneAcl.OzoneACLRights.READ, acl.getRights()); - assertEquals(OzoneAcl.OzoneACLType.USER, acl.getType()); + assertEquals(Arrays.asList(READ), acl.getRights()); + assertEquals(ACLIdentityType.USER, acl.getType()); acl = OzoneAcl.parseAcl("user:bilbo:w"); assertEquals("bilbo", acl.getName()); - assertEquals(OzoneAcl.OzoneACLRights.WRITE, acl.getRights()); - assertEquals(OzoneAcl.OzoneACLType.USER, acl.getType()); + assertEquals(Arrays.asList(WRITE), acl.getRights()); + assertEquals(ACLIdentityType.USER, acl.getType()); - acl = OzoneAcl.parseAcl("group:hobbit:wr"); + acl = OzoneAcl.parseAcl("group:hobbit:a"); assertEquals(acl.getName(), "hobbit"); - assertEquals(OzoneAcl.OzoneACLRights.READ_WRITE, acl.getRights()); - assertEquals(OzoneAcl.OzoneACLType.GROUP, acl.getType()); + assertEquals(Arrays.asList(ALL), acl.getRights()); + assertEquals(ACLIdentityType.GROUP, acl.getType()); - acl = OzoneAcl.parseAcl("world::wr"); + acl = OzoneAcl.parseAcl("world::a"); assertEquals(acl.getName(), ""); - assertEquals(OzoneAcl.OzoneACLRights.READ_WRITE, acl.getRights()); - assertEquals(OzoneAcl.OzoneACLType.WORLD, acl.getType()); + assertEquals(Arrays.asList(ALL), acl.getRights()); + assertEquals(ACLIdentityType.WORLD, acl.getType()); + + acl = OzoneAcl.parseAcl("user:bilbo:rwdlncxy"); + assertEquals(acl.getName(), "bilbo"); + assertEquals(Arrays.asList(READ, WRITE, DELETE, LIST, NONE, CREATE, + READ_ACL, WRITE_ACL), acl.getRights()); + assertEquals(ACLIdentityType.USER, acl.getType()); + + acl = OzoneAcl.parseAcl("group:hadoop:rwdlncxy"); + assertEquals(acl.getName(), "hadoop"); + assertEquals(Arrays.asList(READ, WRITE, DELETE, LIST, NONE, CREATE, + READ_ACL, WRITE_ACL), acl.getRights()); + assertEquals(ACLIdentityType.GROUP, acl.getType()); + + acl = OzoneAcl.parseAcl("world::rwdlncxy"); + assertEquals(acl.getName(), ""); + assertEquals(Arrays.asList(READ, WRITE, DELETE, LIST, NONE, CREATE, + READ_ACL, WRITE_ACL), acl.getRights()); + assertEquals(ACLIdentityType.WORLD, acl.getType()); } } diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestOzoneRpcClientAbstract.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestOzoneRpcClientAbstract.java index bd496d0803..0d32f83250 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestOzoneRpcClientAbstract.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestOzoneRpcClientAbstract.java @@ -82,6 +82,8 @@ import org.apache.hadoop.ozone.om.helpers.OmMultipartInfo; import org.apache.hadoop.ozone.om.helpers.OmMultipartUploadCompleteInfo; import org.apache.hadoop.ozone.s3.util.OzoneS3Util; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLIdentityType; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType; import org.apache.hadoop.test.GenericTestUtils; import org.apache.hadoop.test.LambdaTestUtils; import org.apache.hadoop.util.Time; @@ -260,7 +262,7 @@ public void testCreateBucketWithMetadata() } - + @Test public void testCreateBucket() throws IOException, OzoneException { @@ -420,8 +422,8 @@ public void testCreateBucketWithAcls() throws IOException, OzoneException { String volumeName = UUID.randomUUID().toString(); String bucketName = UUID.randomUUID().toString(); - OzoneAcl userAcl = new OzoneAcl(OzoneAcl.OzoneACLType.USER, "test", - OzoneAcl.OzoneACLRights.READ_WRITE); + OzoneAcl userAcl = new OzoneAcl(ACLIdentityType.USER, "test", + ACLType.READ); List acls = new ArrayList<>(); acls.add(userAcl); store.createVolume(volumeName); @@ -439,8 +441,8 @@ public void testCreateBucketWithAllArgument() throws IOException, OzoneException { String volumeName = UUID.randomUUID().toString(); String bucketName = UUID.randomUUID().toString(); - OzoneAcl userAcl = new OzoneAcl(OzoneAcl.OzoneACLType.USER, "test", - OzoneAcl.OzoneACLRights.READ_WRITE); + OzoneAcl userAcl = new OzoneAcl(ACLIdentityType.USER, "test", + ACLType.ALL); List acls = new ArrayList<>(); acls.add(userAcl); store.createVolume(volumeName); @@ -480,9 +482,7 @@ public void testAddBucketAcl() OzoneVolume volume = store.getVolume(volumeName); volume.createBucket(bucketName); List acls = new ArrayList<>(); - acls.add(new OzoneAcl( - OzoneAcl.OzoneACLType.USER, "test", - OzoneAcl.OzoneACLRights.READ_WRITE)); + acls.add(new OzoneAcl(ACLIdentityType.USER, "test", ACLType.ALL)); OzoneBucket bucket = volume.getBucket(bucketName); bucket.addAcls(acls); OzoneBucket newBucket = volume.getBucket(bucketName); @@ -495,8 +495,8 @@ public void testRemoveBucketAcl() throws IOException, OzoneException { String volumeName = UUID.randomUUID().toString(); String bucketName = UUID.randomUUID().toString(); - OzoneAcl userAcl = new OzoneAcl(OzoneAcl.OzoneACLType.USER, "test", - OzoneAcl.OzoneACLRights.READ_WRITE); + OzoneAcl userAcl = new OzoneAcl(ACLIdentityType.USER, "test", + ACLType.ALL); List acls = new ArrayList<>(); acls.add(userAcl); store.createVolume(volumeName); diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOzoneManager.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOzoneManager.java index 03843bbc25..6d4702fa93 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOzoneManager.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOzoneManager.java @@ -55,6 +55,8 @@ import org.apache.hadoop.ozone.om.helpers.ServiceInfo; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServicePort; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.VolumeList; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLIdentityType; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType; import org.apache.hadoop.ozone.util.OzoneVersionInfo; import org.apache.hadoop.ozone.web.handlers.BucketArgs; import org.apache.hadoop.ozone.web.handlers.KeyArgs; @@ -356,30 +358,29 @@ public void testAccessVolume() throws IOException, OzoneException { createVolumeArgs.setGroups(groupName); storageHandler.createVolume(createVolumeArgs); - OzoneAcl userAcl = new OzoneAcl(OzoneAcl.OzoneACLType.USER, userName, - OzoneAcl.OzoneACLRights.READ_WRITE); + OzoneAcl userAcl = new OzoneAcl(ACLIdentityType.USER, userName, + ACLType.READ); Assert.assertTrue(storageHandler.checkVolumeAccess(volumeName, userAcl)); - OzoneAcl group = new OzoneAcl(OzoneAcl.OzoneACLType.GROUP, groupName[0], - OzoneAcl.OzoneACLRights.READ); + OzoneAcl group = new OzoneAcl(ACLIdentityType.GROUP, groupName[0], + ACLType.READ); Assert.assertTrue(storageHandler.checkVolumeAccess(volumeName, group)); // Create a different user and access should fail String falseUserName = "user" + RandomStringUtils.randomNumeric(5); OzoneAcl falseUserAcl = - new OzoneAcl(OzoneAcl.OzoneACLType.USER, falseUserName, - OzoneAcl.OzoneACLRights.READ_WRITE); + new OzoneAcl(ACLIdentityType.USER, falseUserName, + ACLType.ALL); Assert.assertFalse(storageHandler .checkVolumeAccess(volumeName, falseUserAcl)); // Checking access with user name and Group Type should fail - OzoneAcl falseGroupAcl = new OzoneAcl(OzoneAcl.OzoneACLType.GROUP, userName, - OzoneAcl.OzoneACLRights.READ_WRITE); + OzoneAcl falseGroupAcl = new OzoneAcl(ACLIdentityType.GROUP, userName, + ACLType.ALL); Assert.assertFalse(storageHandler .checkVolumeAccess(volumeName, falseGroupAcl)); // Access for acl type world should also fail OzoneAcl worldAcl = - new OzoneAcl(OzoneAcl.OzoneACLType.WORLD, "", - OzoneAcl.OzoneACLRights.READ); + new OzoneAcl(ACLIdentityType.WORLD, "", ACLType.READ); Assert.assertFalse(storageHandler.checkVolumeAccess(volumeName, worldAcl)); Assert.assertEquals(0, omMetrics.getNumVolumeCheckAccessFails()); diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/ozShell/TestOzoneShell.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/ozShell/TestOzoneShell.java index d3a19c39a4..e8fa1245a0 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/ozShell/TestOzoneShell.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/ozShell/TestOzoneShell.java @@ -44,8 +44,6 @@ import org.apache.hadoop.hdfs.DFSUtil; import org.apache.hadoop.ozone.MiniOzoneCluster; import org.apache.hadoop.ozone.OzoneAcl; -import org.apache.hadoop.ozone.OzoneAcl.OzoneACLRights; -import org.apache.hadoop.ozone.OzoneAcl.OzoneACLType; import org.apache.hadoop.ozone.OzoneConsts; import org.apache.hadoop.ozone.client.OzoneBucket; import org.apache.hadoop.ozone.client.OzoneKey; @@ -59,6 +57,8 @@ import org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes; import org.apache.hadoop.ozone.om.helpers.ServiceInfo; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServicePort; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLIdentityType; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType; import org.apache.hadoop.ozone.web.ozShell.OzoneShell; import org.apache.hadoop.ozone.web.ozShell.Shell; import org.apache.hadoop.ozone.web.request.OzoneQuota; @@ -744,8 +744,9 @@ public void testUpdateBucket() throws Exception { OzoneAcl acl = bucket.getAcls().get(aclSize); assertTrue(acl.getName().equals("frodo") - && acl.getType() == OzoneACLType.USER - && acl.getRights()== OzoneACLRights.READ_WRITE); + && acl.getType() == ACLIdentityType.USER + && acl.getRights().contains(ACLType.READ) + && acl.getRights().contains(ACLType.WRITE)); args = new String[] {"bucket", "update", url + "/" + vol.getName() + "/" + bucketName, "--removeAcl", @@ -756,8 +757,8 @@ public void testUpdateBucket() throws Exception { acl = bucket.getAcls().get(aclSize); assertEquals(1 + aclSize, bucket.getAcls().size()); assertTrue(acl.getName().equals("samwise") - && acl.getType() == OzoneACLType.GROUP - && acl.getRights()== OzoneACLRights.READ); + && acl.getType() == ACLIdentityType.GROUP + && acl.getRights().contains(ACLType.READ)); // test update bucket for a non-exist bucket args = new String[] {"bucket", "update", diff --git a/hadoop-ozone/objectstore-service/src/main/java/org/apache/hadoop/ozone/web/storage/DistributedStorageHandler.java b/hadoop-ozone/objectstore-service/src/main/java/org/apache/hadoop/ozone/web/storage/DistributedStorageHandler.java index d0ab5e210f..42c7238427 100644 --- a/hadoop-ozone/objectstore-service/src/main/java/org/apache/hadoop/ozone/web/storage/DistributedStorageHandler.java +++ b/hadoop-ozone/objectstore-service/src/main/java/org/apache/hadoop/ozone/web/storage/DistributedStorageHandler.java @@ -44,8 +44,10 @@ import org.apache.hadoop.ozone.client.io.OzoneOutputStream; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos; import org.apache.hadoop.ozone.protocolPB.OMPBHelper; -import org.apache.hadoop.ozone.om.OMConfigKeys; import org.apache.hadoop.ozone.OzoneAcl; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLIdentityType; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType; +import org.apache.hadoop.ozone.security.acl.OzoneAclConfig; import org.apache.hadoop.ozone.web.request.OzoneQuota; import org.apache.hadoop.hdds.scm.ScmConfigKeys; import org.apache.hadoop.hdds.scm.XceiverClientManager; @@ -80,8 +82,8 @@ public final class DistributedStorageHandler implements StorageHandler { private final OzoneManagerProtocol ozoneManagerClient; private final XceiverClientManager xceiverClientManager; - private final OzoneAcl.OzoneACLRights userRights; - private final OzoneAcl.OzoneACLRights groupRights; + private final ACLType userRights; + private final ACLType groupRights; private int chunkSize; private final long streamBufferFlushSize; private final long streamBufferMaxSize; @@ -109,10 +111,10 @@ public DistributedStorageHandler(OzoneConfiguration conf, chunkSize = (int)conf.getStorageSize(ScmConfigKeys.OZONE_SCM_CHUNK_SIZE_KEY, ScmConfigKeys.OZONE_SCM_CHUNK_SIZE_DEFAULT, StorageUnit.BYTES); - userRights = conf.getEnum(OMConfigKeys.OZONE_OM_USER_RIGHTS, - OMConfigKeys.OZONE_OM_USER_RIGHTS_DEFAULT); - groupRights = conf.getEnum(OMConfigKeys.OZONE_OM_GROUP_RIGHTS, - OMConfigKeys.OZONE_OM_GROUP_RIGHTS_DEFAULT); + // Get default acl rights for user and group. + OzoneAclConfig aclConfig = conf.getObject(OzoneAclConfig.class); + this.userRights = aclConfig.getUserDefaultRights(); + this.groupRights = aclConfig.getGroupDefaultRights(); if(chunkSize > OzoneConsts.OZONE_SCM_CHUNK_MAX_SIZE) { LOG.warn("The chunk size ({}) is not allowed to be more than" + " the maximum size ({})," @@ -176,8 +178,7 @@ public void createVolume(VolumeArgs args) throws IOException, OzoneException { long quota = args.getQuota() == null ? OzoneConsts.MAX_QUOTA_IN_BYTES : args.getQuota().sizeInBytes(); OzoneAcl userAcl = - new OzoneAcl(OzoneAcl.OzoneACLType.USER, - args.getUserName(), userRights); + new OzoneAcl(ACLIdentityType.USER, args.getUserName(), userRights); OmVolumeArgs.Builder builder = OmVolumeArgs.newBuilder(); builder.setAdminName(args.getAdminName()) .setOwnerName(args.getUserName()) @@ -187,7 +188,7 @@ public void createVolume(VolumeArgs args) throws IOException, OzoneException { if (args.getGroups() != null) { for (String group : args.getGroups()) { OzoneAcl groupAcl = - new OzoneAcl(OzoneAcl.OzoneACLType.GROUP, group, groupRights); + new OzoneAcl(ACLIdentityType.GROUP, group, groupRights); builder.addOzoneAcls(OMPBHelper.convertOzoneAcl(groupAcl)); } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/VolumeManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/VolumeManagerImpl.java index 872d7b6674..7b17550a12 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/VolumeManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/VolumeManagerImpl.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.ozone.om.exceptions.OMException; import org.apache.hadoop.ozone.om.helpers.OmDeleteVolumeResponse; @@ -484,7 +485,8 @@ public boolean checkVolumeAccess(String volume, OzoneAclInfo userAcl) } catch (IOException ex) { if (!(ex instanceof OMException)) { LOG.error("Check volume access failed for volume:{} user:{} rights:{}", - volume, userAcl.getName(), userAcl.getRights(), ex); + volume, userAcl.getName(), + StringUtils.join(userAcl.getRightsList(), ","), ex); } throw ex; } finally { diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestBucketManagerImpl.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestBucketManagerImpl.java index 7fa72fd7d0..a063d11d24 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestBucketManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestBucketManagerImpl.java @@ -42,6 +42,8 @@ import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; +import static org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.*; + /** * Tests BucketManagerImpl, mocks OMMetadataManager for testing. */ @@ -217,8 +219,8 @@ public void testSetBucketPropertyAddACL() throws Exception { OmMetadataManagerImpl metaMgr = createSampleVol(); List acls = new LinkedList<>(); - OzoneAcl ozoneAcl = new OzoneAcl(OzoneAcl.OzoneACLType.USER, - "root", OzoneAcl.OzoneACLRights.READ); + OzoneAcl ozoneAcl = new OzoneAcl(ACLIdentityType.USER, + "root", ACLType.READ); acls.add(ozoneAcl); BucketManager bucketManager = new BucketManagerImpl(metaMgr); OmBucketInfo bucketInfo = OmBucketInfo.newBuilder() @@ -235,8 +237,8 @@ public void testSetBucketPropertyAddACL() throws Exception { Assert.assertEquals("bucketOne", result.getBucketName()); Assert.assertEquals(1, result.getAcls().size()); List addAcls = new LinkedList<>(); - OzoneAcl newAcl = new OzoneAcl(OzoneAcl.OzoneACLType.USER, - "ozone", OzoneAcl.OzoneACLRights.READ); + OzoneAcl newAcl = new OzoneAcl(ACLIdentityType.USER, + "ozone", ACLType.READ); addAcls.add(newAcl); OmBucketArgs bucketArgs = OmBucketArgs.newBuilder() .setVolumeName("sampleVol") @@ -256,10 +258,10 @@ public void testSetBucketPropertyRemoveACL() throws Exception { OmMetadataManagerImpl metaMgr = createSampleVol(); List acls = new LinkedList<>(); - OzoneAcl aclOne = new OzoneAcl(OzoneAcl.OzoneACLType.USER, - "root", OzoneAcl.OzoneACLRights.READ); - OzoneAcl aclTwo = new OzoneAcl(OzoneAcl.OzoneACLType.USER, - "ozone", OzoneAcl.OzoneACLRights.READ); + OzoneAcl aclOne = new OzoneAcl(ACLIdentityType.USER, + "root", ACLType.READ); + OzoneAcl aclTwo = new OzoneAcl(ACLIdentityType.USER, + "ozone", ACLType.READ); acls.add(aclOne); acls.add(aclTwo); BucketManager bucketManager = new BucketManagerImpl(metaMgr); diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/scm/cli/SQLCLI.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/scm/cli/SQLCLI.java index 0c7b7ed263..d4c982dcf9 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/scm/cli/SQLCLI.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/scm/cli/SQLCLI.java @@ -378,7 +378,7 @@ private void insertOMDB(Connection conn, KeyType type, String keyName, for (OzoneAclInfo aclInfo : volumeInfo.getVolumeAclsList()) { String insertAclInfo = String.format(INSERT_ACL_INFO, adminName, ownerName, volumeName, - aclInfo.getType(), aclInfo.getName(), aclInfo.getRights()); + aclInfo.getType(), aclInfo.getName(), aclInfo.getRightsList()); executeSQL(conn, insertAclInfo); } break;