-
Notifications
You must be signed in to change notification settings - Fork 615
HDDS-14935. [STS] Handle Latent Inconsistencies in S3 API Acl Checks #10009
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d1cc9b2
c483af5
6d43f39
b1ed2d2
fd5f08a
ca2a33a
af93237
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,7 @@ | |
| import java.util.LinkedHashMap; | ||
| import java.util.Map; | ||
| import java.util.Objects; | ||
| import java.util.UUID; | ||
| import org.apache.commons.lang3.StringUtils; | ||
| import org.apache.hadoop.hdds.utils.TransactionInfo; | ||
| import org.apache.hadoop.ipc_.ProtobufRpcEngine; | ||
|
|
@@ -50,10 +51,12 @@ | |
| import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerRatisUtils; | ||
| import org.apache.hadoop.ozone.om.request.s3.security.S3AssumeRoleRequest; | ||
| import org.apache.hadoop.ozone.om.response.OMClientResponse; | ||
| import org.apache.hadoop.ozone.om.upgrade.OMLayoutVersionManager; | ||
| import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos; | ||
| import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LayoutVersion; | ||
| import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest; | ||
| import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse; | ||
| import org.apache.hadoop.ozone.security.STSTokenIdentifier; | ||
| import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer; | ||
| import org.apache.hadoop.ozone.security.acl.OzoneObj; | ||
| import org.apache.hadoop.ozone.security.acl.OzoneObjInfo; | ||
|
|
@@ -112,15 +115,66 @@ public OMClientRequest(OMRequest omRequest) { | |
| */ | ||
| public OMRequest preExecute(OzoneManager ozoneManager) | ||
| throws IOException { | ||
| LayoutVersion layoutVersion = LayoutVersion.newBuilder() | ||
| .setVersion(ozoneManager.getVersionManager().getMetadataLayoutVersion()) | ||
| .build(); | ||
| omRequest = getOmRequest().toBuilder() | ||
| .setUserInfo(getUserIfNotExists(ozoneManager)) | ||
| .setLayoutVersion(layoutVersion).build(); | ||
| final OMRequest.Builder requestBuilder = getOmRequest().toBuilder() | ||
| .setUserInfo(getUserIfNotExists(ozoneManager)); | ||
|
|
||
| // VersionManager is always expected in production OzoneManager instances. | ||
| // Some unit tests use a minimal mocked OzoneManager, so perform null check here. | ||
| final OMLayoutVersionManager versionManager = ozoneManager.getVersionManager(); | ||
| if (versionManager != null) { | ||
| final LayoutVersion layoutVersion = LayoutVersion.newBuilder() | ||
| .setVersion(versionManager.getMetadataLayoutVersion()) | ||
| .build(); | ||
| requestBuilder.setLayoutVersion(layoutVersion); | ||
| } | ||
|
|
||
| if (requestBuilder.hasS3Authentication()) { | ||
| final OzoneManagerProtocolProtos.S3Authentication s3Auth = requestBuilder.getS3Authentication(); | ||
| final boolean hasSessionToken = s3Auth.hasSessionToken() && !s3Auth.getSessionToken().isEmpty(); | ||
| final STSTokenIdentifier stsTokenIdentifier = OzoneManager.getStsTokenIdentifier(); | ||
|
|
||
| // This should not happen, so explicitly throw an error. An existing sessionToken | ||
| // implies prior STS validation must have populated the ThreadLocal. | ||
| if (ozoneManager.isSecurityEnabled() && hasSessionToken && stsTokenIdentifier == null) { | ||
| throw new OMException( | ||
| "S3Authentication has session token but no STS token identifier in OzoneManager ThreadLocal", | ||
| OMException.ResultCodes.INVALID_REQUEST); | ||
| } | ||
|
|
||
| requestBuilder.setS3Authentication(resolveS3Authentication(s3Auth, stsTokenIdentifier)); | ||
| } | ||
|
|
||
|
Comment on lines
+118
to
+146
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated to fix all overriding preExecute implementations and to add a checkstyle rule for future ones - 6d43f39 |
||
| omRequest = requestBuilder.build(); | ||
| return omRequest; | ||
| } | ||
|
|
||
| private static OzoneManagerProtocolProtos.S3Authentication resolveS3Authentication( | ||
| OzoneManagerProtocolProtos.S3Authentication s3Auth, STSTokenIdentifier stsTokenIdentifier) { | ||
| final OzoneManagerProtocolProtos.S3Authentication.Builder s3AuthBuilder = s3Auth.toBuilder(); | ||
|
|
||
| if (s3Auth.hasSessionToken() && !s3Auth.getSessionToken().isEmpty() && stsTokenIdentifier != null) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is "s3Auth.hasSessionToken() && !s3Auth.getSessionToken().isEmpty()" and null stsTokenIdentifier allowed?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no this is not allowed. Updated to throw an error if this happens and a unit test coverage - b1ed2d2 |
||
| s3AuthBuilder.setResolvedStsSessionPolicy( | ||
| StringUtils.defaultString(stsTokenIdentifier.getSessionPolicy())); | ||
| s3AuthBuilder.setResolvedStsRoleArn( | ||
| StringUtils.defaultString(stsTokenIdentifier.getRoleArn())); | ||
| s3AuthBuilder.setResolvedStsOriginalAccessKeyId( | ||
| StringUtils.defaultString(stsTokenIdentifier.getOriginalAccessKeyId())); | ||
| s3AuthBuilder.setResolvedStsTempAccessKeyId( | ||
| StringUtils.defaultString(stsTokenIdentifier.getTempAccessKeyId())); | ||
| final UUID secretKeyId = stsTokenIdentifier.getSecretKeyId(); | ||
| s3AuthBuilder.setResolvedStsSecretKeyId( | ||
| secretKeyId != null ? secretKeyId.toString() : ""); | ||
| } else { | ||
| s3AuthBuilder.clearResolvedStsSessionPolicy(); | ||
| s3AuthBuilder.clearResolvedStsRoleArn(); | ||
| s3AuthBuilder.clearResolvedStsOriginalAccessKeyId(); | ||
| s3AuthBuilder.clearResolvedStsTempAccessKeyId(); | ||
| s3AuthBuilder.clearResolvedStsSecretKeyId(); | ||
| } | ||
|
|
||
| return s3AuthBuilder.build(); | ||
| } | ||
|
|
||
| /** | ||
| * Performs any request specific failure handling during request | ||
| * submission. An example of this would be an undo of any steps | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -54,14 +54,15 @@ public class OMBucketSetAclRequest extends OMBucketAclRequest { | |
|
|
||
| @Override | ||
| public OMRequest preExecute(OzoneManager ozoneManager) throws IOException { | ||
| long modificationTime = Time.now(); | ||
| OzoneManagerProtocolProtos.SetAclRequest.Builder setAclRequestBuilder = | ||
| final long modificationTime = Time.now(); | ||
| final OzoneManagerProtocolProtos.SetAclRequest.Builder setAclRequestBuilder = | ||
| getOmRequest().getSetAclRequest().toBuilder() | ||
| .setModificationTime(modificationTime); | ||
|
|
||
| return getOmRequest().toBuilder() | ||
| // super.preExecute resolves S3Authentication (STS) for Ratis apply. Merge SetAclRequest changes on top. | ||
| final OMRequest request = super.preExecute(ozoneManager); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mentioned OMBucketDeleteRequest in the JIRA description. Shall we call the super.preExecute in OMBucketDeleteRequest too?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are two other requests, OMBucketAddAclRequest, OMBucketRemoveAclRequest. So we should consider move this to OMBucketAclRequest.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, we should call
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
updated as part of 6d43f39. I changed the subclasses directly. |
||
| return request.toBuilder() | ||
| .setSetAclRequest(setAclRequestBuilder) | ||
| .setUserInfo(getUserInfo()) | ||
| .build(); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated - c483af5