diff --git a/hadoop-ozone/dist/src/main/compose/ozone-om-ha-s3/test.sh b/hadoop-ozone/dist/src/main/compose/ozone-om-ha-s3/test.sh index 719ad4cbba21..4f2bd0997e0d 100644 --- a/hadoop-ozone/dist/src/main/compose/ozone-om-ha-s3/test.sh +++ b/hadoop-ozone/dist/src/main/compose/ozone-om-ha-s3/test.sh @@ -30,6 +30,8 @@ execute_robot_test scm s3 execute_robot_test scm freon +execute_robot_test scm basic/links.robot + stop_docker_env generate_report diff --git a/hadoop-ozone/dist/src/main/compose/ozonesecure-om-ha/docker-config b/hadoop-ozone/dist/src/main/compose/ozonesecure-om-ha/docker-config index 00820d3d72cd..869fc5e88346 100644 --- a/hadoop-ozone/dist/src/main/compose/ozonesecure-om-ha/docker-config +++ b/hadoop-ozone/dist/src/main/compose/ozonesecure-om-ha/docker-config @@ -55,7 +55,7 @@ HDFS-SITE.XML_dfs.datanode.address=0.0.0.0:1019 HDFS-SITE.XML_dfs.datanode.http.address=0.0.0.0:1012 CORE-SITE.XML_dfs.data.transfer.protection=authentication CORE-SITE.XML_hadoop.security.authentication=kerberos -CORE-SITE.XML_hadoop.security.auth_to_local=RULE:[2:$1@$0](.*)s/.*/root/ +CORE-SITE.XML_hadoop.security.auth_to_local=RULE:[2:$1](testuser2.*) RULE:[2:$1@$0](.*)s/.*/root/ CORE-SITE.XML_hadoop.security.key.provider.path=kms://http@kms:9600/kms diff --git a/hadoop-ozone/dist/src/main/compose/ozonesecure-om-ha/test.sh b/hadoop-ozone/dist/src/main/compose/ozonesecure-om-ha/test.sh index 8893ef6ff790..9fba980e2563 100755 --- a/hadoop-ozone/dist/src/main/compose/ozonesecure-om-ha/test.sh +++ b/hadoop-ozone/dist/src/main/compose/ozonesecure-om-ha/test.sh @@ -30,6 +30,8 @@ execute_robot_test scm kinit.robot execute_robot_test scm freon +execute_robot_test scm basic/links.robot + stop_docker_env generate_report diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java index 3ae843388296..574ec07fe0de 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java @@ -138,6 +138,7 @@ import org.apache.hadoop.ozone.om.ratis.OMTransactionInfo; import org.apache.hadoop.ozone.om.ratis.OzoneManagerRatisServer; import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerRatisUtils; +import org.apache.hadoop.ozone.om.request.OMClientRequest; import org.apache.hadoop.ozone.om.request.file.OMFileRequest; import org.apache.hadoop.ozone.om.snapshot.OzoneManagerSnapshotProvider; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos; @@ -3468,9 +3469,10 @@ private void startJVMPauseMonitor() { jvmPauseMonitor.start(); } - public ResolvedBucket resolveBucketLink(KeyArgs args) throws IOException { + public ResolvedBucket resolveBucketLink(KeyArgs args, + OMClientRequest omClientRequest) throws IOException { return resolveBucketLink( - Pair.of(args.getVolumeName(), args.getBucketName())); + Pair.of(args.getVolumeName(), args.getBucketName()), omClientRequest); } public ResolvedBucket resolveBucketLink(OmKeyArgs args) @@ -3479,10 +3481,35 @@ public ResolvedBucket resolveBucketLink(OmKeyArgs args) Pair.of(args.getVolumeName(), args.getBucketName())); } + public ResolvedBucket resolveBucketLink(Pair requested, + OMClientRequest omClientRequest) + throws IOException { + Pair resolved; + if (isAclEnabled) { + resolved = resolveBucketLink(requested, new HashSet<>(), + omClientRequest.createUGI(), omClientRequest.getRemoteAddress(), + omClientRequest.getHostName()); + } else { + resolved = resolveBucketLink(requested, new HashSet<>(), + null, null, null); + } + return new ResolvedBucket(requested, resolved); + } + + public ResolvedBucket resolveBucketLink(Pair requested) throws IOException { - Pair resolved = - resolveBucketLink(requested, new HashSet<>()); + + Pair resolved; + if (isAclEnabled) { + resolved = resolveBucketLink(requested, new HashSet<>(), + Server.getRemoteUser(), + Server.getRemoteIp(), + Server.getRemoteIp().getHostName()); + } else { + resolved = resolveBucketLink(requested, new HashSet<>(), + null, null, null); + } return new ResolvedBucket(requested, resolved); } @@ -3492,6 +3519,9 @@ public ResolvedBucket resolveBucketLink(Pair requested) * @param volumeAndBucket the bucket to be resolved (if it is a link) * @param visited collects link buckets visited during the resolution to * avoid infinite loops + * @param {@link UserGroupInformation} + * @param remoteAddress + * @param hostName * @return bucket location possibly updated with its actual volume and bucket * after following bucket links * @throws IOException (most likely OMException) if ACL check fails, bucket is @@ -3499,7 +3529,10 @@ public ResolvedBucket resolveBucketLink(Pair requested) */ private Pair resolveBucketLink( Pair volumeAndBucket, - Set> visited) throws IOException { + Set> visited, + UserGroupInformation userGroupInformation, + InetAddress remoteAddress, + String hostName) throws IOException { String volumeName = volumeAndBucket.getLeft(); String bucketName = volumeAndBucket.getRight(); @@ -3515,12 +3548,13 @@ private Pair resolveBucketLink( if (isAclEnabled) { checkAcls(ResourceType.BUCKET, StoreType.OZONE, ACLType.READ, - volumeName, bucketName, null); + volumeName, bucketName, null, userGroupInformation, + remoteAddress, hostName); } return resolveBucketLink( Pair.of(info.getSourceVolume(), info.getSourceBucket()), - visited); + visited, userGroupInformation, remoteAddress, hostName); } @VisibleForTesting diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/OMClientRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/OMClientRequest.java index 0fa9ca1a8d2c..728a62402cbd 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/OMClientRequest.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/OMClientRequest.java @@ -62,6 +62,9 @@ public abstract class OMClientRequest implements RequestAuditor { LoggerFactory.getLogger(OMClientRequest.class); private OMRequest omRequest; + private UserGroupInformation userGroupInformation; + private InetAddress inetAddress; + /** * Stores the result of request execution in * OMClientRequest#validateAndUpdateCache. @@ -160,10 +163,16 @@ public void checkAcls(OzoneManager ozoneManager, */ @VisibleForTesting public UserGroupInformation createUGI() { + + if (userGroupInformation != null) { + return userGroupInformation; + } + if (omRequest.hasUserInfo() && !StringUtils.isBlank(omRequest.getUserInfo().getUserName())) { - return UserGroupInformation.createRemoteUser( + userGroupInformation = UserGroupInformation.createRemoteUser( omRequest.getUserInfo().getUserName()); + return userGroupInformation; } else { // This will never happen, as for every OM request preExecute, we // should add userInfo. @@ -179,9 +188,14 @@ public UserGroupInformation createUGI() { */ @VisibleForTesting public InetAddress getRemoteAddress() throws IOException { + if (inetAddress != null) { + return inetAddress; + } + if (omRequest.hasUserInfo()) { - return InetAddress.getByName(omRequest.getUserInfo() + inetAddress = InetAddress.getByName(omRequest.getUserInfo() .getRemoteAddress()); + return inetAddress; } else { return null; } 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 d863073cd524..567811f1adc0 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 @@ -90,10 +90,10 @@ public OMKeyRequest(OMRequest omRequest) { super(omRequest); } - protected static KeyArgs resolveBucketLink( + protected KeyArgs resolveBucketLink( OzoneManager ozoneManager, KeyArgs keyArgs, Map auditMap) throws IOException { - ResolvedBucket bucket = ozoneManager.resolveBucketLink(keyArgs); + ResolvedBucket bucket = ozoneManager.resolveBucketLink(keyArgs, this); keyArgs = bucket.update(keyArgs); bucket.audit(auditMap); return keyArgs; diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysDeleteRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysDeleteRequest.java index 012df4960e42..68b5a955e3f8 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysDeleteRequest.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysDeleteRequest.java @@ -113,7 +113,7 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, boolean deleteStatus = true; try { ResolvedBucket bucket = ozoneManager.resolveBucketLink( - Pair.of(volumeName, bucketName)); + Pair.of(volumeName, bucketName), this); bucket.audit(auditMap); volumeName = bucket.realVolume(); bucketName = bucket.realBucket(); diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysRenameRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysRenameRequest.java index dbcde6d4ce14..abaa4ae3c074 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysRenameRequest.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysRenameRequest.java @@ -109,7 +109,7 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, try { ResolvedBucket bucket = ozoneManager.resolveBucketLink( - Pair.of(volumeName, bucketName)); + Pair.of(volumeName, bucketName), this); bucket.audit(auditMap); volumeName = bucket.realVolume(); bucketName = bucket.realBucket(); diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMTrashRecoverRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMTrashRecoverRequest.java index 232a0fb6c0e4..eca5294b3a3d 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMTrashRecoverRequest.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMTrashRecoverRequest.java @@ -89,7 +89,7 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, OMClientResponse omClientResponse = null; try { ResolvedBucket bucket = ozoneManager.resolveBucketLink( - Pair.of(volumeName, destinationBucket)); + Pair.of(volumeName, destinationBucket), this); volumeName = bucket.realVolume(); destinationBucket = bucket.realBucket(); 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 c09bf8651e70..7d8b5fc99792 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 @@ -26,6 +26,7 @@ import org.apache.hadoop.ozone.om.ResolvedBucket; import org.apache.hadoop.ozone.om.helpers.OzoneFSUtils; import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper; +import org.apache.hadoop.ozone.om.request.OMClientRequest; import org.apache.hadoop.ozone.om.response.OMClientResponse; import org.apache.hadoop.hdds.utils.db.cache.CacheKey; import org.junit.After; @@ -88,7 +89,8 @@ public void setup() throws Exception { auditLogger = Mockito.mock(AuditLogger.class); when(ozoneManager.getAuditLogger()).thenReturn(auditLogger); Mockito.doNothing().when(auditLogger).logWrite(any(AuditMessage.class)); - when(ozoneManager.resolveBucketLink(any(KeyArgs.class))) + when(ozoneManager.resolveBucketLink(any(KeyArgs.class), + any(OMClientRequest.class))) .thenReturn(new ResolvedBucket(Pair.of("", ""), Pair.of("", ""))); } diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyRequest.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyRequest.java index cb35e2b9358d..116ba5ce8fb4 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyRequest.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyRequest.java @@ -27,6 +27,7 @@ import org.apache.hadoop.ozone.om.KeyManager; import org.apache.hadoop.ozone.om.KeyManagerImpl; import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper; +import org.apache.hadoop.ozone.om.request.OMClientRequest; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.KeyArgs; import org.junit.After; import org.junit.Before; @@ -160,9 +161,11 @@ public void setup() throws Exception { dataSize = 1000L; Pair volumeAndBucket = Pair.of(volumeName, bucketName); - when(ozoneManager.resolveBucketLink(any(KeyArgs.class))) + when(ozoneManager.resolveBucketLink(any(KeyArgs.class), + any(OMClientRequest.class))) .thenReturn(new ResolvedBucket(volumeAndBucket, volumeAndBucket)); - when(ozoneManager.resolveBucketLink(any(Pair.class))) + when(ozoneManager.resolveBucketLink(any(Pair.class), + any(OMClientRequest.class))) .thenReturn(new ResolvedBucket(volumeAndBucket, volumeAndBucket)); } diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/multipart/TestS3MultipartRequest.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/multipart/TestS3MultipartRequest.java index f0f040f39479..f2c5b6679119 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/multipart/TestS3MultipartRequest.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/multipart/TestS3MultipartRequest.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.util.List; +import org.apache.hadoop.ozone.om.request.OMClientRequest; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -82,7 +83,8 @@ public void setup() throws Exception { auditLogger = Mockito.mock(AuditLogger.class); when(ozoneManager.getAuditLogger()).thenReturn(auditLogger); Mockito.doNothing().when(auditLogger).logWrite(any(AuditMessage.class)); - when(ozoneManager.resolveBucketLink(any(KeyArgs.class))) + when(ozoneManager.resolveBucketLink(any(KeyArgs.class), + any(OMClientRequest.class))) .thenAnswer(inv -> { KeyArgs args = (KeyArgs) inv.getArguments()[0]; return new ResolvedBucket(