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]

Reply via email to