fmorg-git commented on code in PR #11134:
URL: https://github.com/apache/ozone/pull/11134#discussion_r3920638149


##########
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3AssumeRoleRequest.java:
##########
@@ -274,13 +298,134 @@ String getSessionPolicy(OzoneManager ozoneManager, 
String originalAccessKeyId, S
 
     final Set<OzoneGrant> grants = Strings.isNullOrEmpty(awsIamPolicy) ?
         null :
-        IamSessionPolicyResolver.resolve(awsIamPolicy, volumeName, 
IamSessionPolicyResolver.AuthorizerType.RANGER);
+        resolveGrantsAgainstBucketLinks(
+            IamSessionPolicyResolver.resolve(awsIamPolicy, volumeName, 
IamSessionPolicyResolver.AuthorizerType.RANGER),
+            (linkVolume, linkBucket) -> 
ozoneManager.resolveBucketLink(Pair.of(linkVolume, linkBucket), true, false));
 
     return ozoneManager.getAccessAuthorizer().generateAssumeRoleSessionPolicy(
         new org.apache.hadoop.ozone.security.acl.AssumeRoleRequest(
             hostName, remoteIp, ugi, targetRoleName, grants));
   }
 
+  /**
+   * Rewrites the resolved session-policy grants so that any bucket, key, or 
prefix resource that names a
+   * bucket link is anchored to the link's source volume and bucket - the 
resource paths the OM authorizes
+   * against once the link is resolved at request time. READ on each link 
bucket in the chain (and, when the
+   * chain crosses volumes, READ on each distinct volume except the requested 
one) is retained so OM can follow
+   * every hop at request time, which keeps the generated token as small as 
possible.
+   * <p>
+   * The link target is resolved when the token is generated, so the token 
grants access to whatever the link
+   * points to at that moment. If the link is later re-pointed, the token no 
longer grants access to the new
+   * target.
+   *
+   * @param grants       the grants produced by {@link 
IamSessionPolicyResolver}, possibly {@code null}
+   * @param linkResolver resolves a (volume, bucket) pair to its link target
+   * @return the link-aware grants, or the input unchanged when there is 
nothing to resolve
+   */
+  @VisibleForTesting
+  static Set<OzoneGrant> resolveGrantsAgainstBucketLinks(Set<OzoneGrant> 
grants,
+      BucketLinkResolver linkResolver) throws IOException {
+    if (grants == null || grants.isEmpty()) {
+      return grants;
+    }
+
+    final Map<Pair<String, String>, ResolvedBucket> resolutionCache = new 
HashMap<>();
+    final Set<IOzoneObj> linkFollowObjects = new LinkedHashSet<>();
+    final Set<OzoneGrant> resolvedGrants = new LinkedHashSet<>();
+
+    for (OzoneGrant grant : grants) {
+      final Set<IOzoneObj> resolvedObjects = new LinkedHashSet<>();
+      for (IOzoneObj object : grant.getObjects()) {
+        resolvedObjects.add(
+            resolveObjectAgainstBucketLink((OzoneObj) object, linkResolver, 
resolutionCache, linkFollowObjects));
+      }
+      resolvedGrants.add(new OzoneGrant(resolvedObjects, 
grant.getPermissions(), grant.getS3Actions()));
+    }
+
+    // Retain only the READ required to follow each link hop at request time.
+    if (!linkFollowObjects.isEmpty()) {
+      resolvedGrants.add(new OzoneGrant(linkFollowObjects, 
EnumSet.of(ACLType.READ)));
+    }
+
+    return resolvedGrants;
+  }
+
+  /**
+   * Resolves a single grant object against its bucket link. Bucket, key, and 
prefix objects that name a
+   * link bucket are rewritten to the link's source volume and bucket, and the 
READ needed to follow each hop
+   * in the link chain is collected in {@code linkFollowObjects}. All other 
objects (volume resources and
+   * wildcard buckets) are returned unchanged.
+   */
+  private static IOzoneObj resolveObjectAgainstBucketLink(OzoneObj object, 
BucketLinkResolver linkResolver,
+      Map<Pair<String, String>, ResolvedBucket> resolutionCache, 
Set<IOzoneObj> linkFollowObjects)
+      throws IOException {
+    final OzoneObj.ResourceType resourceType = object.getResourceType();
+    if (resourceType != OzoneObj.ResourceType.BUCKET
+        && resourceType != OzoneObj.ResourceType.KEY
+        && resourceType != OzoneObj.ResourceType.PREFIX) {
+      return object;
+    }
+
+    final String volumeName = object.getVolumeName();
+    final String bucketName = object.getBucketName();
+    // Wildcard or unspecified names cannot correspond to a concrete link 
bucket.
+    if (StringUtils.isBlank(volumeName) || StringUtils.isBlank(bucketName) || 
hasWildcard(volumeName) ||
+        hasWildcard(bucketName)) {
+      return object;
+    }
+
+    final Pair<String, String> requested = Pair.of(volumeName, bucketName);
+    ResolvedBucket resolved = resolutionCache.get(requested);
+    if (resolved == null) {
+      resolved = linkResolver.resolve(volumeName, bucketName);
+      resolutionCache.put(requested, resolved);
+    }

Review Comment:
   this doesn't appear to be a valid issue today



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to