Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gateway/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -5371,6 +5371,7 @@ def _is_user_authorized(self, source: SessionSource) -> bool:
user_id = source.user_id
if not user_id:
return False
team_id = (source.guild_id or "").strip()

platform_env_map = {
Platform.TELEGRAM: "TELEGRAM_ALLOWED_USERS",
Expand Down
22 changes: 16 additions & 6 deletions hermes_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7189,19 +7189,22 @@ def _ensure_fhs_path_guard() -> None:
if not fhs_link.is_symlink() and not fhs_link.exists():
return

# Probe a fresh non-login interactive bash the way the user will use it.
# ``bash -i -c`` sources ~/.bashrc but NOT ~/.bash_profile or /etc/profile,
# which is the exact scenario where RHEL root loses /usr/local/bin.
home = os.environ.get("HOME") or "/root"
# Resolve root's real home from passwd instead of trusting HOME.
try:
import pwd

home = pwd.getpwuid(0).pw_dir or "/root"
except Exception:
home = "/root"
try:
probe = subprocess.run(
[
"env",
"-i",
f"HOME={home}",
"PATH=/usr/local/bin:/usr/bin:/bin",
f"TERM={os.environ.get('TERM', 'dumb')}",
"bash",
"-i",
"-c",
"command -v hermes",
],
Expand All @@ -7221,7 +7224,14 @@ def _ensure_fhs_path_guard() -> None:
wrote_any = False
for candidate in (".bashrc", ".bash_profile"):
cfg = Path(home) / candidate
if not cfg.is_file():
if not cfg.is_file() or cfg.is_symlink():
continue
try:
st = cfg.stat()
except OSError:
continue
# Root-only: refuse files not owned by root or writable by group/world.
if st.st_uid != 0 or (st.st_mode & 0o022):
continue
try:
existing = cfg.read_text(errors="replace")
Expand Down
23 changes: 18 additions & 5 deletions scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1145,11 +1145,15 @@ EOF
# /root/.bash_profile doesn't either. So verify with `command -v` and
# fall back to writing a PATH guard into /root/.bashrc when needed.
if [ "$ROOT_FHS_LAYOUT" = true ]; then
ROOT_HOME="$(getent passwd root 2>/dev/null | cut -d: -f6)"
[ -n "$ROOT_HOME" ] || ROOT_HOME="/root"
if [ ! -d "$ROOT_HOME" ]; then
ROOT_HOME="/root"
fi
export PATH="$command_link_dir:$PATH"
# Probe a fresh non-login interactive bash the way the user will use it.
# `bash -i -c` sources ~/.bashrc but NOT ~/.bash_profile or /etc/profile,
# which is the exact scenario where RHEL root loses /usr/local/bin.
if env -i HOME="$HOME" TERM="${TERM:-dumb}" bash -i -c 'command -v hermes' \
# Probe a minimal shell environment without sourcing user startup files.
if env -i PATH="/usr/local/bin:/usr/bin:/bin" HOME="$ROOT_HOME" TERM="${TERM:-dumb}" \
bash -c 'command -v hermes' \
>/dev/null 2>&1; then
log_info "/usr/local/bin is already on PATH for all shells"
log_success "hermes command ready"
Expand All @@ -1159,8 +1163,17 @@ EOF
log_info "hermes not on PATH in non-login shells (common on RHEL-family)"
PATH_LINE='export PATH="/usr/local/bin:$PATH"'
PATH_COMMENT='# Hermes Agent — ensure /usr/local/bin is on PATH (RHEL non-login shells)'
for SHELL_CONFIG in "$HOME/.bashrc" "$HOME/.bash_profile"; do
for SHELL_CONFIG in "$ROOT_HOME/.bashrc" "$ROOT_HOME/.bash_profile"; do
[ -f "$SHELL_CONFIG" ] || continue
[ ! -L "$SHELL_CONFIG" ] || continue
if ! stat_out="$(stat -Lc '%u %a' "$SHELL_CONFIG" 2>/dev/null)"; then
continue
fi
shell_uid="${stat_out% *}"
shell_mode="${stat_out#* }"
# Must be root-owned and not group/world writable.
[ "$shell_uid" = "0" ] || continue
[ $((8#$shell_mode & 022)) -eq 0 ] || continue
if ! grep -v '^[[:space:]]*#' "$SHELL_CONFIG" 2>/dev/null \
| grep -qE 'PATH=.*(/usr/local/bin|\$command_link_dir)'; then
echo "" >> "$SHELL_CONFIG"
Expand Down
Loading