diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/OmConfig.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/OmConfig.java index a4ef5827387a..849436b14f3e 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/OmConfig.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/OmConfig.java @@ -117,6 +117,14 @@ public class OmConfig extends ReconfigurableConfig { private String groupDefaultRights; private Set groupDefaultRightSet; + @Config(key = "object.creation.ignore.client.acls", + defaultValue = "false", + type = ConfigType.BOOLEAN, + tags = {ConfigTag.OM, ConfigTag.SECURITY}, + description = "Ignore ACLs sent by client to OzoneManager during volume/bucket/key creation." + ) + private boolean ignoreClientACLs; + public long getRatisBasedFinalizationTimeout() { return ratisBasedFinalizationTimeout; } @@ -181,6 +189,14 @@ private Set getGroupDefaultRightSet() { : ACLType.parseList(groupDefaultRights); } + public boolean ignoreClientACLs() { + return ignoreClientACLs; + } + + public void setIgnoreClientACLs(boolean ignore) { + ignoreClientACLs = ignore; + } + @PostConstruct public void validate() { if (maxListSize <= 0) { diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/bucket/OMBucketCreateRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/bucket/OMBucketCreateRequest.java index 0416924e033f..5afdfb9c5176 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/bucket/OMBucketCreateRequest.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/bucket/OMBucketCreateRequest.java @@ -336,7 +336,7 @@ private void addDefaultAcls(OmBucketInfo omBucketInfo, List acls = new ArrayList<>(); // Add default acls acls.addAll(getDefaultAclList(createUGIForApi(), ozoneManager.getConfig())); - if (omBucketInfo.getAcls() != null) { + if (omBucketInfo.getAcls() != null && !ozoneManager.getConfig().ignoreClientACLs()) { // Add acls for bucket creator. acls.addAll(omBucketInfo.getAcls()); } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyRequest.java index 03af4822627a..cc538d7110a1 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyRequest.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyRequest.java @@ -333,7 +333,7 @@ protected List getAclsForKey(KeyArgs keyArgs, List acls = new ArrayList<>(); acls.addAll(getDefaultAclList(createUGIForApi(), config)); - if (keyArgs.getAclsList() != null) { + if (!keyArgs.getAclsList().isEmpty() && !config.ignoreClientACLs()) { acls.addAll(OzoneAclUtil.fromProtobuf(keyArgs.getAclsList())); } @@ -407,7 +407,9 @@ protected List getAclsForDir(KeyArgs keyArgs, OmBucketInfo bucketInfo, } // add acls from clients - acls.addAll(OzoneAclUtil.fromProtobuf(keyArgs.getAclsList())); + if (!keyArgs.getAclsList().isEmpty() && !config.ignoreClientACLs()) { + acls.addAll(OzoneAclUtil.fromProtobuf(keyArgs.getAclsList())); + } acls = acls.stream().distinct().collect(Collectors.toList()); return acls; } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeCreateRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeCreateRequest.java index e91757ee3a23..c5f0ca7823f7 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeCreateRequest.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeCreateRequest.java @@ -168,7 +168,7 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, Execut List listOfAcls = getDefaultAclList(UserGroupInformation.createRemoteUser(owner), ozoneManager.getConfig()); // ACLs from VolumeArgs - if (omVolumeArgs.getAcls() != null) { + if (omVolumeArgs.getAcls() != null && !ozoneManager.getConfig().ignoreClientACLs()) { listOfAcls.addAll(omVolumeArgs.getAcls()); } // Remove the duplicates diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/bucket/TestOMBucketCreateRequest.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/bucket/TestOMBucketCreateRequest.java index 774a5c9ea0b8..09f3e0b9d601 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/bucket/TestOMBucketCreateRequest.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/bucket/TestOMBucketCreateRequest.java @@ -20,6 +20,7 @@ import static org.apache.hadoop.ozone.om.request.OMRequestTestUtils.newBucketInfoBuilder; import static org.apache.hadoop.ozone.om.request.OMRequestTestUtils.newCreateBucketRequest; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -27,10 +28,13 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; +import java.util.List; import java.util.UUID; import org.apache.hadoop.hdds.client.DefaultReplicationConfig; import org.apache.hadoop.hdds.client.ECReplicationConfig; +import org.apache.hadoop.hdds.protocol.proto.HddsProtos; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.StorageTypeProto; +import org.apache.hadoop.ozone.OzoneAcl; import org.apache.hadoop.ozone.om.OMConfigKeys; import org.apache.hadoop.ozone.om.OMMetadataManager; import org.apache.hadoop.ozone.om.OzoneManager; @@ -48,6 +52,8 @@ import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.util.Time; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; /** * Tests OMBucketCreateRequest class, which handles CreateBucket request. @@ -320,6 +326,44 @@ public void testAcceptNonS3CompliantBucketNameCreationWithStrictS3False() } } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void testIgnoreClientACL(boolean ignoreClientACLs) throws Exception { + ozoneManager.getConfig().setIgnoreClientACLs(ignoreClientACLs); + + String volumeName = UUID.randomUUID().toString(); + String bucketName = UUID.randomUUID().toString(); + OMRequestTestUtils.addVolumeToDB(volumeName, omMetadataManager, 10000L); + + // create a bucket + String acl = "user:ozone:a"; + OzoneManagerProtocolProtos.BucketInfo.Builder builder = + OzoneManagerProtocolProtos.BucketInfo.newBuilder() + .setBucketName(bucketName) + .setVolumeName(volumeName) + .setStorageType(HddsProtos.StorageTypeProto.SSD) + .setIsVersionEnabled(false) + .setQuotaInBytes(5000L) + .addAcls(OzoneAcl.toProtobuf(OzoneAcl.parseAcl(acl))); + OMRequest originalRequest = newCreateBucketRequest(builder).build(); + OMBucketCreateRequest omBucketCreateRequest = new OMBucketCreateRequest(originalRequest); + OMRequest modifiedRequest = omBucketCreateRequest.preExecute(ozoneManager); + OMBucketCreateRequest testRequest = new OMBucketCreateRequest(modifiedRequest); + testRequest.setUGI(UserGroupInformation.getCurrentUser()); + OMClientResponse resp = testRequest.validateAndUpdateCache(ozoneManager, 1); + assertEquals(resp.getOMResponse().getStatus().toString(), OMException.ResultCodes.OK.toString()); + + // Check ACLs + OmBucketInfo bucket = + omMetadataManager.getBucketTable().get(omMetadataManager.getBucketKey(volumeName, bucketName)); + List aclList = bucket.getAcls(); + if (ignoreClientACLs) { + assertFalse(aclList.contains(OzoneAcl.parseAcl(acl))); + } else { + assertTrue(aclList.contains(OzoneAcl.parseAcl(acl))); + } + } + private void acceptBucketCreationHelper(String volumeName, String bucketName) throws Exception { OMBucketCreateRequest omBucketCreateRequest = diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/file/TestOMDirectoryCreateRequest.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/file/TestOMDirectoryCreateRequest.java index 1cdf808ff3d8..1b096070ea3f 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/file/TestOMDirectoryCreateRequest.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/file/TestOMDirectoryCreateRequest.java @@ -21,6 +21,7 @@ import static org.apache.hadoop.ozone.OzoneConsts.OZONE_URI_DELIMITER; import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status.VOLUME_NOT_FOUND; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -495,6 +496,44 @@ public void testCreateDirectoryInheritParentDefaultAcls() throws Exception { } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void testIgnoreClientACL(boolean ignoreClientACLs) throws Exception { + ozoneManager.getConfig().setIgnoreClientACLs(ignoreClientACLs); + + String volumeName = "vol1"; + String bucketName = "bucket1"; + String keyName = genRandomKeyName(); + + // Add volume and bucket entries to DB. + OMRequestTestUtils.addVolumeAndBucketToDB(volumeName, bucketName, + omMetadataManager); + + String ozoneAll = "user:ozone:a"; + List aclList = new ArrayList<>(); + aclList.add(OzoneAcl.parseAcl(ozoneAll)); + OMRequest omRequest = createDirectoryRequest(volumeName, bucketName, + OzoneFSUtils.addTrailingSlashIfNeeded(keyName), aclList); + OMDirectoryCreateRequest omDirectoryCreateRequest = + new OMDirectoryCreateRequest(omRequest, getBucketLayout()); + + OMRequest modifiedOmRequest = omDirectoryCreateRequest.preExecute(ozoneManager); + omDirectoryCreateRequest = new OMDirectoryCreateRequest(modifiedOmRequest, getBucketLayout()); + omDirectoryCreateRequest.setUGI(UserGroupInformation.getCurrentUser()); + + OMClientResponse omClientResponse = omDirectoryCreateRequest.validateAndUpdateCache(ozoneManager, 100L); + assertEquals(OzoneManagerProtocolProtos.Status.OK, omClientResponse.getOMResponse().getStatus()); + + OmKeyInfo keyInfo = omMetadataManager.getKeyTable(getBucketLayout()).get( + omMetadataManager.getOzoneDirKey(volumeName, bucketName, keyName)); + + if (ignoreClientACLs) { + assertFalse(keyInfo.getAcls().contains(OzoneAcl.parseAcl(ozoneAll))); + } else { + assertTrue(keyInfo.getAcls().contains(OzoneAcl.parseAcl(ozoneAll))); + } + } + private void verifyDirectoriesInheritAcls(String volumeName, String bucketName, String keyName, List bucketAcls) throws IOException { @@ -520,19 +559,31 @@ private void verifyDirectoriesInheritAcls(String volumeName, } } + private OMRequest createDirectoryRequest(String volumeName, String bucketName, String keyName) { + return createDirectoryRequest(volumeName, bucketName, keyName, null); + } + /** * Create OMRequest which encapsulates CreateDirectory request. * @param volumeName * @param bucketName * @param keyName + * @param acls * @return OMRequest */ private OMRequest createDirectoryRequest(String volumeName, String bucketName, - String keyName) { - return OMRequest.newBuilder().setCreateDirectoryRequest( - CreateDirectoryRequest.newBuilder().setKeyArgs( - KeyArgs.newBuilder().setVolumeName(volumeName) - .setBucketName(bucketName).setKeyName(keyName))) + String keyName, List acls) { + KeyArgs.Builder builder = KeyArgs.newBuilder() + .setVolumeName(volumeName) + .setBucketName(bucketName) + .setKeyName(keyName); + if (acls != null) { + for (OzoneAcl acl : acls) { + builder.addAcls(OzoneAcl.toProtobuf(acl)); + } + } + return OMRequest.newBuilder() + .setCreateDirectoryRequest(CreateDirectoryRequest.newBuilder().setKeyArgs(builder)) .setCmdType(OzoneManagerProtocolProtos.Type.CreateDirectory) .setClientId(UUID.randomUUID().toString()).build(); } diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/file/TestOMDirectoryCreateRequestWithFSO.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/file/TestOMDirectoryCreateRequestWithFSO.java index 0c87607c3bcc..4abeaf25d0c8 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/file/TestOMDirectoryCreateRequestWithFSO.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/file/TestOMDirectoryCreateRequestWithFSO.java @@ -20,6 +20,7 @@ import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationFactor.THREE; import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status.VOLUME_NOT_FOUND; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -73,6 +74,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; /** * Test OM directory create request - prefix layout. @@ -709,6 +712,45 @@ public void testCreateDirectoryInheritParentDefaultAcls() throws Exception { } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void testIgnoreClientACL(boolean ignoreClientACLs) throws Exception { + ozoneManager.getConfig().setIgnoreClientACLs(ignoreClientACLs); + + String volumeName = "vol1"; + String bucketName = "bucket1"; + List dirs = new ArrayList<>(); + String keyName = createDirKey(dirs, 3); + + // Add volume and bucket entries to DB. + OMRequestTestUtils.addVolumeAndBucketToDB(volumeName, bucketName, + omMetadataManager, getBucketLayout()); + + String ozoneAll = "user:ozone:a"; + List aclList = new ArrayList<>(); + aclList.add(OzoneAcl.parseAcl(ozoneAll)); + OMRequest omRequest = createDirectoryRequest(volumeName, bucketName, + OzoneFSUtils.addTrailingSlashIfNeeded(keyName), aclList); + OMDirectoryCreateRequest omDirectoryCreateRequest = + new OMDirectoryCreateRequest(omRequest, getBucketLayout()); + + OMRequest modifiedOmRequest = omDirectoryCreateRequest.preExecute(ozoneManager); + omDirectoryCreateRequest = new OMDirectoryCreateRequest(modifiedOmRequest, getBucketLayout()); + omDirectoryCreateRequest.setUGI(UserGroupInformation.getCurrentUser()); + + OMClientResponse omClientResponse = omDirectoryCreateRequest.validateAndUpdateCache(ozoneManager, 100L); + assertEquals(OzoneManagerProtocolProtos.Status.OK, omClientResponse.getOMResponse().getStatus()); + + OmKeyInfo keyInfo = omMetadataManager.getKeyTable(getBucketLayout()).get( + omMetadataManager.getOzoneDirKey(volumeName, bucketName, keyName)); + + if (ignoreClientACLs) { + assertFalse(keyInfo.getAcls().contains(OzoneAcl.parseAcl(ozoneAll))); + } else { + assertTrue(keyInfo.getAcls().contains(OzoneAcl.parseAcl(ozoneAll))); + } + } + private void verifyDirectoriesInheritAcls(List dirs, long volumeId, long bucketId, List bucketAcls) throws IOException { @@ -788,22 +830,34 @@ private void verifyDirectoriesNotInCache(List dirs, } } + private OMRequest createDirectoryRequest(String volumeName, String bucketName, String keyName) { + return createDirectoryRequest(volumeName, bucketName, keyName, null); + } + /** * Create OMRequest which encapsulates CreateDirectory request. * * @param volumeName * @param bucketName * @param keyName + * @param acls * @return OMRequest */ private OMRequest createDirectoryRequest(String volumeName, String bucketName, - String keyName) { - return OMRequest.newBuilder().setCreateDirectoryRequest( - CreateDirectoryRequest.newBuilder().setKeyArgs( - KeyArgs.newBuilder().setVolumeName(volumeName) - .setBucketName(bucketName).setKeyName(keyName))) - .setCmdType(OzoneManagerProtocolProtos.Type.CreateDirectory) - .setClientId(UUID.randomUUID().toString()).build(); + String keyName, List acls) { + KeyArgs.Builder builder = KeyArgs.newBuilder() + .setVolumeName(volumeName) + .setBucketName(bucketName) + .setKeyName(keyName); + if (acls != null) { + for (OzoneAcl acl : acls) { + builder.addAcls(OzoneAcl.toProtobuf(acl)); + } + } + return OMRequest.newBuilder() + .setCreateDirectoryRequest(CreateDirectoryRequest.newBuilder().setKeyArgs(builder)) + .setCmdType(OzoneManagerProtocolProtos.Type.CreateDirectory) + .setClientId(UUID.randomUUID().toString()).build(); } private BucketLayout getBucketLayout() { diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/file/TestOMFileCreateRequest.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/file/TestOMFileCreateRequest.java index 53bde85940cd..a5b792c717e6 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/file/TestOMFileCreateRequest.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/file/TestOMFileCreateRequest.java @@ -17,6 +17,7 @@ package org.apache.hadoop.ozone.om.request.file; +import static org.apache.hadoop.ozone.om.request.OMRequestTestUtils.addVolumeAndBucketToDB; import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status.BUCKET_NOT_FOUND; import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status.DIRECTORY_NOT_FOUND; import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status.FILE_ALREADY_EXISTS; @@ -24,6 +25,7 @@ import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status.VOLUME_NOT_FOUND; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -52,6 +54,7 @@ import org.apache.hadoop.ozone.om.helpers.OmDirectoryInfo; import org.apache.hadoop.ozone.om.helpers.OmKeyInfo; import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfo; +import org.apache.hadoop.ozone.om.lock.OzoneLockProvider; import org.apache.hadoop.ozone.om.request.OMRequestTestUtils; import org.apache.hadoop.ozone.om.request.key.TestOMKeyRequest; import org.apache.hadoop.ozone.om.response.OMClientResponse; @@ -63,6 +66,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; /** * Tests OMFileCreateRequest. @@ -520,6 +524,40 @@ protected void verifyInheritAcls(List dirs, OmKeyInfo omKeyInfo, } } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void testIgnoreClientACL(boolean ignoreClientACLs) throws Exception { + ozoneManager.getConfig().setIgnoreClientACLs(ignoreClientACLs); + when(ozoneManager.getOzoneLockProvider()).thenReturn(new OzoneLockProvider(true, true)); + addVolumeAndBucketToDB(volumeName, bucketName, omMetadataManager, getBucketLayout()); + // create file + String ozoneAll = "user:ozone:a"; + List aclList = new ArrayList<>(); + aclList.add(OzoneAcl.parseAcl(ozoneAll)); + + // Recursive create file with acls inherited from bucket DEFAULT acls + OMRequest omRequest = createFileRequest(volumeName, bucketName, + keyName, HddsProtos.ReplicationFactor.ONE, + HddsProtos.ReplicationType.RATIS, false, true, aclList); + + OMFileCreateRequest omFileCreateRequest = getOMFileCreateRequest(omRequest); + OMRequest modifiedOmRequest = omFileCreateRequest.preExecute(ozoneManager); + long id = modifiedOmRequest.getCreateFileRequest().getClientID(); + + omFileCreateRequest = getOMFileCreateRequest(modifiedOmRequest); + OMClientResponse omFileCreateResponse = + omFileCreateRequest.validateAndUpdateCache(ozoneManager, 100L); + assertEquals(OzoneManagerProtocolProtos.Status.OK, + omFileCreateResponse.getOMResponse().getStatus()); + + OmKeyInfo omKeyInfo = verifyPathInOpenKeyTable(keyName, id, true); + if (ignoreClientACLs) { + assertFalse(omKeyInfo.getAcls().contains(OzoneAcl.parseAcl(ozoneAll))); + } else { + assertTrue(omKeyInfo.getAcls().contains(OzoneAcl.parseAcl(ozoneAll))); + } + } + @ParameterizedTest @CsvSource(value = { ".snapshot/keyName,Cannot create key under path reserved for snapshot: .snapshot/", @@ -617,11 +655,27 @@ protected OMRequest createFileRequest( HddsProtos.ReplicationFactor replicationFactor, HddsProtos.ReplicationType replicationType, boolean overWrite, boolean recursive) { + return createFileRequest(volumeName, bucketName, keyName, replicationFactor, + replicationType, overWrite, recursive, null); + } + + @SuppressWarnings("checkstyle:ParameterNumber") + @Nonnull + protected OMRequest createFileRequest( + String volumeName, String bucketName, String keyName, + HddsProtos.ReplicationFactor replicationFactor, + HddsProtos.ReplicationType replicationType, boolean overWrite, + boolean recursive, List acls) { KeyArgs.Builder keyArgs = KeyArgs.newBuilder() .setVolumeName(volumeName).setBucketName(bucketName) .setKeyName(keyName).setFactor(replicationFactor) .setType(replicationType).setDataSize(dataSize); + if (acls != null) { + for (OzoneAcl acl : acls) { + keyArgs.addAcls(OzoneAcl.toProtobuf(acl)); + } + } CreateFileRequest createFileRequest = CreateFileRequest.newBuilder() .setKeyArgs(keyArgs) diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyCreateRequest.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyCreateRequest.java index 4b53233e98c8..b4cf5f7cc142 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyCreateRequest.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyCreateRequest.java @@ -32,6 +32,7 @@ import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status.OK; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -563,6 +564,34 @@ public void testCreationWithoutMetadataFollowedByOverwriteWithMetadata( verifyMetadataInResponse(overwriteResponse, overwriteMetadata); } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void testIgnoreClientACL(boolean ignoreClientACLs) throws Exception { + ozoneManager.getConfig().setIgnoreClientACLs(ignoreClientACLs); + when(ozoneManager.getOzoneLockProvider()).thenReturn(new OzoneLockProvider(true, true)); + addVolumeAndBucketToDB(volumeName, bucketName, omMetadataManager, getBucketLayout()); + // create file + String ozoneAll = "user:ozone:a"; + List aclList = new ArrayList<>(); + aclList.add(OzoneAcl.parseAcl(ozoneAll)); + OMRequest modifiedOmRequest = + doPreExecute(createKeyRequest(false, 0, keyName, emptyMap(), emptyMap(), aclList)); + OMKeyCreateRequest omKeyCreateRequest = getOMKeyCreateRequest(modifiedOmRequest); + long id = modifiedOmRequest.getCreateKeyRequest().getClientID(); + String openKey = getOpenKey(id); + OMClientResponse omKeyCreateResponse = + omKeyCreateRequest.validateAndUpdateCache(ozoneManager, 100L); + checkResponse(modifiedOmRequest, omKeyCreateResponse, id, false, + omKeyCreateRequest.getBucketLayout()); + + OmKeyInfo omKeyInfo = omMetadataManager.getOpenKeyTable(getBucketLayout()).get(openKey); + if (ignoreClientACLs) { + assertFalse(omKeyInfo.getAcls().contains(OzoneAcl.parseAcl(ozoneAll))); + } else { + assertTrue(omKeyInfo.getAcls().contains(OzoneAcl.parseAcl(ozoneAll))); + } + } + private void verifyMetadataInResponse(OMClientResponse response, Map expectedMetadata) { // Extract metadata from the response diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeCreateRequest.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeCreateRequest.java index e12b703d50af..628e163a6afb 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeCreateRequest.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeCreateRequest.java @@ -19,14 +19,18 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; +import java.util.List; import java.util.UUID; +import org.apache.hadoop.ozone.OzoneAcl; import org.apache.hadoop.ozone.om.OzoneManager; import org.apache.hadoop.ozone.om.exceptions.OMException; import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs; @@ -40,6 +44,8 @@ import org.apache.hadoop.ozone.security.acl.OzoneObj; import org.apache.hadoop.ozone.storage.proto.OzoneManagerStorageProtos; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; /** * Tests create volume request. @@ -71,7 +77,7 @@ public void testValidateAndUpdateCacheWithZeroMaxUserVolumeCount() long expectedObjId = ozoneManager.getObjectIdFromTxId(txLogIndex); OMRequest originalRequest = createVolumeRequest(volumeName, adminName, - ownerName); + ownerName, "world::a"); OMVolumeCreateRequest omVolumeCreateRequest = new OMVolumeCreateRequest(originalRequest); @@ -97,7 +103,7 @@ public void testValidateAndUpdateCacheSuccess() throws Exception { String ownerName = "user1"; OMRequest originalRequest = createVolumeRequest(volumeName, adminName, - ownerName); + ownerName, "world::a"); OMVolumeCreateRequest omVolumeCreateRequest = new OMVolumeCreateRequest(originalRequest); @@ -158,7 +164,7 @@ public void testValidateAndUpdateCacheSuccess() throws Exception { // Create another volume for the user. originalRequest = createVolumeRequest("vol1", adminName, - ownerName); + ownerName, "world::a"); omVolumeCreateRequest = new OMVolumeCreateRequest(originalRequest); @@ -186,7 +192,7 @@ public void testValidateAndUpdateCacheWithVolumeAlreadyExists() OMRequestTestUtils.addVolumeToDB(volumeName, omMetadataManager); OMRequest originalRequest = createVolumeRequest(volumeName, adminName, - ownerName); + ownerName, "world::a"); OMVolumeCreateRequest omVolumeCreateRequest = new OMVolumeCreateRequest(originalRequest); @@ -218,7 +224,7 @@ public void preExecutePermissionDeniedWhenAclEnabled() throws Exception { when(ozoneManager.getAclsEnabled()).thenReturn(true); OMRequest originalRequest = createVolumeRequest(volumeName, adminName, - ownerName); + ownerName, "world::a"); OMVolumeCreateRequest req = new OMVolumeCreateRequest(originalRequest) { @Override @@ -276,11 +282,40 @@ public void testAcceptNonS3CompliantVolumeNameCreationWithStrictS3False() } } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void testIgnoreClientACL(boolean ignoreClientACLs) throws Exception { + ozoneManager.getConfig().setIgnoreClientACLs(ignoreClientACLs); + + String volumeName = UUID.randomUUID().toString(); + String adminName = "user1"; + String ownerName = "user1"; + String acl = "user:ozone:a"; + OMRequest originalRequest = createVolumeRequest(volumeName, adminName, ownerName, acl); + OMVolumeCreateRequest omVolumeCreateRequest = new OMVolumeCreateRequest(originalRequest); + OMRequest modifiedRequest = omVolumeCreateRequest.preExecute(ozoneManager); + omVolumeCreateRequest = new OMVolumeCreateRequest(modifiedRequest); + OMClientResponse omClientResponse = + omVolumeCreateRequest.validateAndUpdateCache(ozoneManager, 1); + OzoneManagerProtocolProtos.OMResponse omResponse = omClientResponse.getOMResponse(); + assertNotNull(omResponse.getCreateVolumeResponse()); + assertEquals(OzoneManagerProtocolProtos.Status.OK, omResponse.getStatus()); + + // Check ACLs + OmVolumeArgs volumeArgs = omMetadataManager.getVolumeTable().get(omMetadataManager.getVolumeKey(volumeName)); + List aclList = volumeArgs.getAcls(); + if (ignoreClientACLs) { + assertFalse(aclList.contains(OzoneAcl.parseAcl(acl))); + } else { + assertTrue(aclList.contains(OzoneAcl.parseAcl(acl))); + } + } + private void acceptVolumeCreationHelper(String volumeName, String adminName, String ownerName) throws Exception { OMRequest originalRequest = createVolumeRequest(volumeName, adminName, - ownerName); + ownerName, "world::a"); OMVolumeCreateRequest omVolumeCreateRequest = new OMVolumeCreateRequest(originalRequest); OMRequest modifiedRequest = omVolumeCreateRequest.preExecute(ozoneManager); @@ -312,7 +347,7 @@ private void doPreExecute(String volumeName, String adminName, String ownerName) throws Exception { OMRequest originalRequest = createVolumeRequest(volumeName, adminName, - ownerName); + ownerName, "world::a"); OMVolumeCreateRequest omVolumeCreateRequest = new OMVolumeCreateRequest(originalRequest); diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeRequest.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeRequest.java index 9a4b4e76c6d1..36c6034207c0 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeRequest.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeRequest.java @@ -26,6 +26,7 @@ import java.nio.file.Path; import java.util.UUID; import org.apache.hadoop.hdds.conf.OzoneConfiguration; +import org.apache.hadoop.ozone.OzoneAcl; import org.apache.hadoop.ozone.audit.AuditLogger; import org.apache.hadoop.ozone.audit.AuditMessage; import org.apache.hadoop.ozone.om.OMConfigKeys; @@ -90,13 +91,17 @@ public void stop() { * @param volumeName * @param adminName * @param ownerName + * @param acl * @return OMRequest */ - static OMRequest createVolumeRequest(String volumeName, - String adminName, - String ownerName) { - VolumeInfo volumeInfo = VolumeInfo.newBuilder().setVolume(volumeName) - .setAdminName(adminName).setOwnerName(ownerName).build(); + static OMRequest createVolumeRequest(String volumeName, String adminName, + String ownerName, String acl) { + VolumeInfo volumeInfo = VolumeInfo.newBuilder() + .setVolume(volumeName) + .setAdminName(adminName) + .setOwnerName(ownerName) + .addVolumeAcls(OzoneAcl.toProtobuf(OzoneAcl.parseAcl(acl))) + .build(); CreateVolumeRequest createVolumeRequest = CreateVolumeRequest.newBuilder().setVolumeInfo(volumeInfo).build();