From 8720c46f360fd157d99a9d6394f182abd198ed28 Mon Sep 17 00:00:00 2001
From: Ruslan Fialkovsky <103181800+ruslanfialkovskii@users.noreply.github.com>
Date: Fri, 20 Sep 2024 04:36:02 +0200
Subject: [PATCH] [ZEPPELIN-6094] Fix broken impersonation
### What is this PR for?
A few sentences describing the overall goals of the pull request's commits.
The issue stems from the way the interpreter.sh script handles the ZEPPELIN_IMPERSONATE_CMD and constructs the command to be executed. Specifically, the command string passed to bash -c is not being properly formed as a single string, causing exec to fail when it tries to execute the impersonation command.
1. Command Construction: When ZEPPELIN_IMPERSONATE_CMD is set, the script attempts to build an array INTERPRETER_RUN_COMMAND that includes this command. However, if ZEPPELIN_IMPERSONATE_CMD is a string, it gets added as a single element to the array, leading to incorrect command parsing.
2. bash -c Behavior: The -c option in bash expects a single string argument that contains the command to execute. If this command is split into multiple array elements, bash misinterprets it, causing failures when it encounters shell built-ins like source.
3. exec Execution: The exec command replaces the shell with the specified command. If the command is not correctly formatted, exec cannot find it, resulting in errors like exec: sudo -H -u rfialkovskii bash -c: not found.
To fix the issue needs to adjust how the command is constructed in interpreter.sh when ZEPPELIN_IMPERSONATE_CMD is used. Specifically, the command string passed to bash -c is a single, properly formatted string.
Needs:
Define ZEPPELIN_IMPERSONATE_CMD as an Array.
Modify interpreter.sh to Build a Single Command String:
### What type of PR is it?
Bug Fix
### What is the Jira issue?
[* Open an issue on Jira https://issues.apache.org/jira/browse/ZEPPELIN/
(https://issues.apache.org/jira/browse/ZEPPELIN-6094)
### How should this be tested?
Enable shiro auth, configure impersonation and try to run any interpreter under impersonated user
### Screenshots (if appropriate)
### Questions:
* Does the license files need to update?
No
* Is there breaking changes for older versions?
Yes, needs to change env from:
export ZEPPELIN_IMPERSONATE_CMD='sudo -H -u "${ZEPPELIN_IMPERSONATE_USER}" bash -c'
to:
export ZEPPELIN_IMPERSONATE_CMD=(sudo -H -u "${ZEPPELIN_IMPERSONATE_USER}" bash -c)
* Does this needs documentation?
Yes
Closes #4835 from ruslanfialkovskii/ZEPPELIN-6094-Fix-broken-impersonation.
Signed-off-by: Cheng Pan
---
bin/interpreter.sh | 18 ++++++++++++------
conf/zeppelin-env.sh.template | 2 +-
docs/usage/interpreter/user_impersonation.md | 2 +-
3 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/bin/interpreter.sh b/bin/interpreter.sh
index aaa9b0a15a0..cf8501bb3cf 100755
--- a/bin/interpreter.sh
+++ b/bin/interpreter.sh
@@ -247,13 +247,19 @@ addJarInDirForIntp "${LOCAL_INTERPRETER_REPO}"
if [[ -n "$ZEPPELIN_IMPERSONATE_USER" ]]; then
if [[ "${INTERPRETER_ID}" != "spark" || "$ZEPPELIN_IMPERSONATE_SPARK_PROXY_USER" == "false" ]]; then
- suid="$(id -u "${ZEPPELIN_IMPERSONATE_USER}")"
- if [[ -n "${suid}" || -z "${SPARK_SUBMIT}" ]]; then
- INTERPRETER_RUN_COMMAND+=("${ZEPPELIN_IMPERSONATE_RUN_CMD[@]}")
- if [[ -f "${ZEPPELIN_CONF_DIR}/zeppelin-env.sh" ]]; then
- INTERPRETER_RUN_COMMAND+=("source" "${ZEPPELIN_CONF_DIR}/zeppelin-env.sh;")
- fi
+ # Build the command string
+ COMMAND_STRING=""
+ if [[ -f "${ZEPPELIN_CONF_DIR}/zeppelin-env.sh" ]]; then
+ COMMAND_STRING+="source ${ZEPPELIN_CONF_DIR}/zeppelin-env.sh; "
fi
+
+ # Add interpreter command to the command string
+ IFS=' ' read -r -a JAVA_INTP_OPTS_ARRAY <<< "${JAVA_INTP_OPTS}"
+ IFS=' ' read -r -a ZEPPELIN_INTP_MEM_ARRAY <<< "${ZEPPELIN_INTP_MEM}"
+ COMMAND_STRING+="${ZEPPELIN_RUNNER} ${JAVA_INTP_OPTS_ARRAY[@]} ${ZEPPELIN_INTP_MEM_ARRAY[@]} -cp '${ZEPPELIN_INTP_CLASSPATH_OVERRIDES}:${ZEPPELIN_INTP_CLASSPATH}' ${ZEPPELIN_SERVER} ${CALLBACK_HOST} ${PORT} ${INTP_GROUP_ID} ${INTP_PORT}"
+
+ # Set INTERPRETER_RUN_COMMAND with the impersonation command and command string
+ INTERPRETER_RUN_COMMAND=("${ZEPPELIN_IMPERSONATE_CMD[@]}" "${COMMAND_STRING}")
fi
fi
diff --git a/conf/zeppelin-env.sh.template b/conf/zeppelin-env.sh.template
index e27a688becd..755849f053b 100644
--- a/conf/zeppelin-env.sh.template
+++ b/conf/zeppelin-env.sh.template
@@ -108,5 +108,5 @@
# export HBASE_CONF_DIR= # (optional) Alternatively, configuration directory can be set to point to the directory that has hbase-site.xml
#### Zeppelin impersonation configuration
-# export ZEPPELIN_IMPERSONATE_CMD # Optional, when user want to run interpreter as end web user. eg) 'sudo -H -u ${ZEPPELIN_IMPERSONATE_USER} bash -c '
+# export ZEPPELIN_IMPERSONATE_CMD # Optional, when user want to run interpreter as end web user. eg) (sudo -H -u "${ZEPPELIN_IMPERSONATE_USER}" bash -c)
# export ZEPPELIN_IMPERSONATE_SPARK_PROXY_USER #Optional, by default is true; can be set to false if you don't want to use --proxy-user option with Spark interpreter when impersonation enabled
diff --git a/docs/usage/interpreter/user_impersonation.md b/docs/usage/interpreter/user_impersonation.md
index 722f89f2668..6572161a98f 100644
--- a/docs/usage/interpreter/user_impersonation.md
+++ b/docs/usage/interpreter/user_impersonation.md
@@ -47,7 +47,7 @@ cat ~/.ssh/id_rsa.pub | ssh user1@localhost 'cat >> .ssh/authorized_keys'
Alternatively instead of password-less, user can override ZEPPELIN_IMPERSONATE_CMD in zeppelin-env.sh
```bash
-export ZEPPELIN_IMPERSONATE_CMD='sudo -H -u ${ZEPPELIN_IMPERSONATE_USER} bash -c '
+export ZEPPELIN_IMPERSONATE_CMD=(sudo -H -u "${ZEPPELIN_IMPERSONATE_USER}" bash -c)
```