This is an automated email from the ASF dual-hosted git repository.
smengcl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push:
new f7b7985243f Handle missing RPC user in S3SecretRequestHelper.
f7b7985243f is described below
commit f7b7985243fa461745e10d636ee46dca63fe4416
Author: Siyao Meng <[email protected]>
AuthorDate: Tue Oct 6 16:16:27 2026 -0700
Handle missing RPC user in S3SecretRequestHelper.
Co-authored-by: Claude Opus 5.5 <[email protected]>
---
.../om/request/s3/security/OMSetSecretRequest.java | 2 +-
.../om/request/s3/security/S3GetSecretRequest.java | 2 +-
.../s3/security/S3RevokeSTSTokenRequest.java | 2 +-
.../request/s3/security/S3RevokeSecretRequest.java | 2 +-
.../request/s3/security/S3SecretRequestHelper.java | 8 +++++-
.../s3/security/TestS3GetSecretRequest.java | 30 +++++++++++++++++++++
.../s3/security/TestS3RevokeSTSTokenRequest.java | 15 +++++++++++
.../s3/security/TestS3SecretRequestHelper.java | 31 +++++++++++++++++-----
8 files changed, 81 insertions(+), 11 deletions(-)
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/OMSetSecretRequest.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/OMSetSecretRequest.java
index 9f8d6ca1ee2..c4e7d02f94b 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/OMSetSecretRequest.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/OMSetSecretRequest.java
@@ -89,7 +89,7 @@ public OMRequest preExecute(OzoneManager ozoneManager) throws
IOException {
}
final UserGroupInformation ugi =
- S3SecretRequestHelper.getOrCreateUgi(accessId);
+ S3SecretRequestHelper.getOrCreateUgi(ozoneManager, accessId);
// Permission check
S3SecretRequestHelper.checkAccessIdSecretOpPermission(
ozoneManager, ugi, accessId);
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3GetSecretRequest.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3GetSecretRequest.java
index c0609d7a52e..c0551d89298 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3GetSecretRequest.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3GetSecretRequest.java
@@ -71,7 +71,7 @@ public OMRequest preExecute(OzoneManager ozoneManager) throws
IOException {
final String accessId = s3GetSecretRequest.getKerberosID();
final UserGroupInformation ugi =
- S3SecretRequestHelper.getOrCreateUgi(accessId);
+ S3SecretRequestHelper.getOrCreateUgi(ozoneManager, accessId);
// Permission check
S3SecretRequestHelper.checkAccessIdSecretOpPermission(
ozoneManager, ugi, accessId);
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSTSTokenRequest.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSTSTokenRequest.java
index 02e6cac1b3d..eedcdc1be42 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSTSTokenRequest.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSTSTokenRequest.java
@@ -79,7 +79,7 @@ public OMRequest preExecute(OzoneManager ozoneManager) throws
IOException {
// to revoke its temporary STS credentials.
final String originalAccessKeyId = revokeReq.getOriginalAccessKeyId();
- final UserGroupInformation ugi =
S3SecretRequestHelper.getOrCreateUgi(originalAccessKeyId);
+ final UserGroupInformation ugi =
S3SecretRequestHelper.getOrCreateUgi(ozoneManager, originalAccessKeyId);
S3SecretRequestHelper.checkAccessIdSecretOpPermission(ozoneManager, ugi,
originalAccessKeyId);
if (!ozoneManager.getS3SecretManager().hasS3Secret(originalAccessKeyId)) {
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSecretRequest.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSecretRequest.java
index f74d5a57977..0d1bf068735 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSecretRequest.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSecretRequest.java
@@ -55,7 +55,7 @@ public OMRequest preExecute(OzoneManager ozoneManager) throws
IOException {
omRequest.getRevokeS3SecretRequest();
final String accessId = s3RevokeSecretRequest.getKerberosID();
final UserGroupInformation ugi =
- S3SecretRequestHelper.getOrCreateUgi(accessId);
+ S3SecretRequestHelper.getOrCreateUgi(ozoneManager, accessId);
// Permission check
S3SecretRequestHelper.checkAccessIdSecretOpPermission(
ozoneManager, ugi, accessId);
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3SecretRequestHelper.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3SecretRequestHelper.java
index 8c266289e8d..2bab31d37f6 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3SecretRequestHelper.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3SecretRequestHelper.java
@@ -46,11 +46,17 @@ private S3SecretRequestHelper() {
* Retrieves thread-local UGI for request or construct new one
* based on provided accessId.
*
+ * @param ozoneManager OzoneManager instance.
* @param accessId user identifier from request.
* @return {@link UserGroupInformation} instance.
+ * @throws OMException if security is enabled and the request has no RPC
user.
*/
- public static UserGroupInformation getOrCreateUgi(String accessId) {
+ public static UserGroupInformation getOrCreateUgi(OzoneManager ozoneManager,
String accessId) throws OMException {
final UserGroupInformation ugi = ProtobufRpcEngine.Server.getRemoteUser();
+ if (ugi == null && ozoneManager.isSecurityEnabled()) {
+ throw new OMException("S3 secret operations on accessId '" + accessId +
"' require an RPC user."
+ + " Send the request over the OM RPC transport.",
ResultCodes.PERMISSION_DENIED);
+ }
if (ugi == null && Strings.isNotEmpty(accessId)) {
return UserGroupInformation.createRemoteUser(accessId, KERBEROS);
} else {
diff --git
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3GetSecretRequest.java
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3GetSecretRequest.java
index 5f23bfb14e2..ec62e983337 100644
---
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3GetSecretRequest.java
+++
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3GetSecretRequest.java
@@ -376,6 +376,36 @@ public void testGetSecretOfAnotherUserAsNonAdmin() throws
IOException {
processFailedSecretRequest(USER_CAROL);
}
+ @Test
+ public void testSecretRequestsWithoutRpcUser() throws IOException {
+ // Create the secret first so that the set request passes its existence
check.
+ processSuccessSecretRequest(USER_ALICE, 1, true);
+ when(ozoneManager.isSecurityEnabled()).thenReturn(true);
+ Server.getCurCall().remove();
+
+ assertPreExecuteDenied(new
S3GetSecretRequest(s3GetSecretRequest(USER_ALICE)));
+ assertPreExecuteDenied(new OMSetSecretRequest(OMRequest.newBuilder()
+ .setClientId(UUID.randomUUID().toString())
+ .setCmdType(Type.SetS3Secret)
+
.setSetS3SecretRequest(OzoneManagerProtocolProtos.SetS3SecretRequest.newBuilder()
+ .setAccessId(USER_ALICE)
+ .setSecretKey("secretKey12345")
+ .build())
+ .build()));
+ assertPreExecuteDenied(new S3RevokeSecretRequest(OMRequest.newBuilder()
+ .setClientId(UUID.randomUUID().toString())
+ .setCmdType(Type.RevokeS3Secret)
+
.setRevokeS3SecretRequest(OzoneManagerProtocolProtos.RevokeS3SecretRequest.newBuilder()
+ .setKerberosID(USER_ALICE)
+ .build())
+ .build()));
+ }
+
+ private void assertPreExecuteDenied(OMClientRequest request) {
+ OMException e = assertThrows(OMException.class, () ->
request.preExecute(ozoneManager));
+ assertEquals(ResultCodes.PERMISSION_DENIED, e.getResult());
+ }
+
@Test
public void testGetSecretOfAnotherUserAsS3Admin() throws IOException {
// This effectively makes alice an S3 admin.
diff --git
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3RevokeSTSTokenRequest.java
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3RevokeSTSTokenRequest.java
index 1b6caed9cb4..8c7832804c5 100644
---
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3RevokeSTSTokenRequest.java
+++
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3RevokeSTSTokenRequest.java
@@ -108,6 +108,21 @@ public void
testPreExecuteFailsForNonOwnerOfOriginalAccessKey() throws Exception
assertEquals(OMException.ResultCodes.USER_MISMATCH, ex.getResult());
}
+ @Test
+ public void testPreExecuteFailsWithoutRpcUser() throws Exception {
+ final String originalAccessKeyId = "original-access-key-id";
+
+ OMException ex;
+ try (OzoneManager ozoneManager = mock(OzoneManager.class)) {
+ configureOzoneManagerForPreExecute(ozoneManager, originalAccessKeyId,
true);
+ when(ozoneManager.isSecurityEnabled()).thenReturn(true);
+
+ final OMClientRequest omClientRequest = new
S3RevokeSTSTokenRequest(buildRevokeOmRequest(originalAccessKeyId));
+ ex = assertThrows(OMException.class, () ->
omClientRequest.preExecute(ozoneManager));
+ }
+ assertEquals(OMException.ResultCodes.PERMISSION_DENIED, ex.getResult());
+ }
+
@Test
public void testPreExecuteSucceedsForOriginalAccessKeyOwner() throws
Exception {
// Verify that preExecute allows the owner of the original access key ID
from the revoke request
diff --git
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3SecretRequestHelper.java
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3SecretRequestHelper.java
index 163d412717a..42364003c0b 100644
---
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3SecretRequestHelper.java
+++
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3SecretRequestHelper.java
@@ -21,9 +21,14 @@
import static org.apache.hadoop.security.UserGroupInformation.createRemoteUser;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import org.apache.hadoop.ipc_.ExternalCall;
import org.apache.hadoop.ipc_.Server;
+import org.apache.hadoop.ozone.om.OzoneManager;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authentication.util.KerberosName;
import org.junit.jupiter.api.AfterEach;
@@ -34,6 +39,7 @@ class TestS3SecretRequestHelper {
private static final String TEST_ACCESS_ID = "access/[email protected]";
private UserGroupInformation testUgi;
private UserGroupInformation expectedUgi;
+ private OzoneManager ozoneManager;
@BeforeEach
void setUp() {
@@ -43,6 +49,7 @@ void setUp() {
"DEFAULT");
testUgi = createRemoteUser(TEST_ACCESS_ID, KERBEROS);
expectedUgi = createRemoteUser(TEST_ACCESS_ID, KERBEROS);
+ ozoneManager = mock(OzoneManager.class);
}
@AfterEach
@@ -51,21 +58,33 @@ void tearDown() {
}
@Test
- void testGettingUgiFromCall() {
+ void testGettingUgiFromCall() throws Exception {
Server.getCurCall().set(new StubCall(testUgi));
compareUgi(expectedUgi,
- S3SecretRequestHelper.getOrCreateUgi(TEST_ACCESS_ID));
+ S3SecretRequestHelper.getOrCreateUgi(ozoneManager,
TEST_ACCESS_ID));
}
@Test
- void testGettingUgiFromAccessId() {
+ void testGettingUgiFromAccessId() throws Exception {
compareUgi(expectedUgi,
- S3SecretRequestHelper.getOrCreateUgi(TEST_ACCESS_ID));
+ S3SecretRequestHelper.getOrCreateUgi(ozoneManager,
TEST_ACCESS_ID));
}
@Test
- void testGettingUgiWithNoAccessId() {
- assertNull(S3SecretRequestHelper.getOrCreateUgi(null));
+ void testGettingUgiWithNoAccessId() throws Exception {
+ assertNull(S3SecretRequestHelper.getOrCreateUgi(ozoneManager, null));
+ }
+
+ @Test
+ void testGettingUgiWithSecurityEnabled() throws Exception {
+ when(ozoneManager.isSecurityEnabled()).thenReturn(true);
+
+ OMException e = assertThrows(OMException.class,
+ () -> S3SecretRequestHelper.getOrCreateUgi(ozoneManager,
TEST_ACCESS_ID));
+ assertEquals(OMException.ResultCodes.PERMISSION_DENIED, e.getResult());
+
+ Server.getCurCall().set(new StubCall(testUgi));
+ compareUgi(expectedUgi, S3SecretRequestHelper.getOrCreateUgi(ozoneManager,
TEST_ACCESS_ID));
}
private static void compareUgi(UserGroupInformation expected,
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]