You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by om...@apache.org on 2023/02/24 21:43:28 UTC
[hadoop] 02/02: HDFS-16901: RBF: Propagates real user's username via the caller context, when a proxy user is being used. (#5346)
This is an automated email from the ASF dual-hosted git repository.
omalley pushed a commit to branch branch-3.3
in repository https://gitbox.apache.org/repos/asf/hadoop.git
commit 5fe19a0f01644dee22a847ac9497e097cadc7866
Author: Simbarashe Dzinamarira <sd...@linkedin.com>
AuthorDate: Wed Feb 22 13:58:44 2023 -0800
HDFS-16901: RBF: Propagates real user's username via the caller context, when a proxy user is being used. (#5346)
---
.../java/org/apache/hadoop/ipc/CallerContext.java | 1 +
.../server/federation/router/RouterRpcClient.java | 11 ++++--
.../server/federation/router/TestRouterRpc.java | 41 ++++++++++++++++++++++
3 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/CallerContext.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/CallerContext.java
index dbd9184a2b9..ba627adc2c4 100644
--- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/CallerContext.java
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/CallerContext.java
@@ -47,6 +47,7 @@ public final class CallerContext {
// field names
public static final String CLIENT_IP_STR = "clientIp";
public static final String CLIENT_PORT_STR = "clientPort";
+ public static final String REAL_USER_STR = "realUser";
/** The caller context.
*
diff --git a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RouterRpcClient.java b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RouterRpcClient.java
index 6c55edde112..c4d408dd007 100644
--- a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RouterRpcClient.java
+++ b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RouterRpcClient.java
@@ -423,7 +423,7 @@ public class RouterRpcClient {
+ router.getRouterId());
}
- addClientIpToCallerContext();
+ addClientInfoToCallerContext(ugi);
Object ret = null;
if (rpcMonitor != null) {
@@ -541,19 +541,24 @@ public class RouterRpcClient {
/**
* For tracking which is the actual client address.
- * It adds trace info "clientIp:ip" and "clientPort:port"
+ * It adds trace info "clientIp:ip", "clientPort:port" and "realUser:userName"
* in the caller context, removing the old values if they were
* already present.
*/
- private void addClientIpToCallerContext() {
+ private void addClientInfoToCallerContext(UserGroupInformation ugi) {
CallerContext ctx = CallerContext.getCurrent();
String origContext = ctx == null ? null : ctx.getContext();
byte[] origSignature = ctx == null ? null : ctx.getSignature();
+ String realUser = null;
+ if (ugi.getRealUser() != null) {
+ realUser = ugi.getRealUser().getUserName();
+ }
CallerContext.Builder builder =
new CallerContext.Builder("", contextFieldSeparator)
.append(CallerContext.CLIENT_IP_STR, Server.getRemoteAddress())
.append(CallerContext.CLIENT_PORT_STR,
Integer.toString(Server.getRemotePort()))
+ .append(CallerContext.REAL_USER_STR, realUser)
.setSignature(origSignature);
// Append the original caller context
if (origContext != null) {
diff --git a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterRpc.java b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterRpc.java
index ae0908894de..48420ed416c 100644
--- a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterRpc.java
+++ b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterRpc.java
@@ -39,6 +39,7 @@ import static org.junit.Assert.fail;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
+import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
@@ -210,6 +211,14 @@ public class TestRouterRpc {
cluster.setIndependentDNs();
Configuration conf = new Configuration();
+ // Setup proxy users.
+ conf.set("hadoop.proxyuser.testRealUser.groups", "*");
+ conf.set("hadoop.proxyuser.testRealUser.hosts", "*");
+ String loginUser = UserGroupInformation.getLoginUser().getUserName();
+ conf.set(String.format("hadoop.proxyuser.%s.groups", loginUser), "*");
+ conf.set(String.format("hadoop.proxyuser.%s.hosts", loginUser), "*");
+ // Enable IP proxy users.
+ conf.set(DFSConfigKeys.DFS_NAMENODE_IP_PROXY_USERS, "placeholder");
conf.setInt(DFSConfigKeys.DFS_LIST_LIMIT, 5);
cluster.addNamenodeOverrides(conf);
// Start NNs and DNs and wait until ready
@@ -1871,6 +1880,38 @@ public class TestRouterRpc {
assertTrue(verifyFileExists(routerFS, dirPath));
}
+ @Test
+ public void testRealUserPropagationInCallerContext()
+ throws IOException, InterruptedException {
+ GenericTestUtils.LogCapturer auditlog =
+ GenericTestUtils.LogCapturer.captureLogs(FSNamesystem.auditLog);
+
+ // Current callerContext is null
+ assertNull(CallerContext.getCurrent());
+
+ UserGroupInformation loginUser = UserGroupInformation.getLoginUser();
+ UserGroupInformation realUser = UserGroupInformation
+ .createUserForTesting("testRealUser", new String[]{"group"});
+ UserGroupInformation proxyUser = UserGroupInformation
+ .createProxyUser("testProxyUser", realUser);
+ FileSystem proxyFs = proxyUser.doAs(
+ (PrivilegedExceptionAction<FileSystem>) () -> router.getFileSystem());
+ proxyFs.listStatus(new Path("/"));
+
+
+ final String logOutput = auditlog.getOutput();
+ // Login user, which is used as the router's user, is different from the realUser.
+ assertNotEquals(loginUser.getUserName(), realUser.getUserName());
+ // Login user is used in the audit log's ugi field.
+ assertTrue("The login user is the proxyUser in the UGI field",
+ logOutput.contains(String.format("ugi=%s (auth:PROXY) via %s (auth:SIMPLE)",
+ proxyUser.getUserName(),
+ loginUser.getUserName())));
+ // Real user is added to the caller context.
+ assertTrue("The audit log should contain the real user.",
+ logOutput.contains(String.format("realUser:%s", realUser.getUserName())));
+ }
+
@Test
public void testSetBalancerBandwidth() throws Exception {
long defaultBandwidth =
---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org