pmbootstrap-meow/pmb/chroot/user.py
Oliver Smith 37a7f3924d
Fix preserving proxy variables (MR 2237)
Fix "pmbootstrap chroot" and others not passing the proxy environment
variables correctly. Thanks to notfound405 for pointing this out!

Instead of only preserving proxy environment variables in
pmb.helpers.run_core, which should never be called directly, do it in
the calling functions:

* pmb.helpers.run.user
* pmb.helpers.run.root
* pmb.chroot.root
* pmb.chroot.user

This fixes that the environment variables were only really passed by
pmb.helpers.run.user, because the other functions would result in
something like:
  HTTP_PROXY=mytestproxy sudo env -i /usr/bin/sh -c '…'
This is needed to either elevate to root, or to elevate to root first
and then enter the chroot as root or user. Due to the "env -i", the
environment intentionally gets cleaned, but unintentionally also removes
the proxy environment variables that were explicitly set.

By adjusting the functions, they now run a variant of:
  sudo env -i /usr/bin/sh -c 'HTTP_PROXY=mytestproxy …'

The escaping is simplified in this example, run "pmbootstrap -v" to see
the not very readable, but proper escaping with shutil.quote().

Remove the previous test for preserving the environment variables in
pmb.helpers.run_core (as it should never be called directly), and test
instead the new behavior.

Fixes: issue 2299
Fixes: 13c4ac42 ("pmb.helpers.run_core: fix proxy env var logic")
2024-01-25 20:12:53 +00:00

44 lines
1.5 KiB
Python

# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import pmb.chroot.root
import pmb.helpers.run
import pmb.helpers.run_core
def user(args, cmd, suffix="native", working_dir="/", output="log",
output_return=False, check=None, env={}, auto_init=True):
"""
Run a command inside a chroot as "user". We always use the BusyBox
implementation of 'su', because other implementations may override the PATH
environment variable (#1071).
:param env: dict of environment variables to be passed to the command, e.g.
{"JOBS": "5"}
:param auto_init: automatically initialize the chroot
See pmb.helpers.run_core.core() for a detailed description of all other
arguments and the return value.
"""
env = env.copy()
pmb.helpers.run_core.add_proxy_env_vars(env)
if "HOME" not in env:
env["HOME"] = "/home/pmos"
flat_cmd = pmb.helpers.run_core.flat_cmd(cmd, env=env)
cmd = ["busybox", "su", "pmos", "-c", flat_cmd]
return pmb.chroot.root(args, cmd, suffix, working_dir, output,
output_return, check, {}, auto_init,
add_proxy_env_vars=False)
def exists(args, username, suffix="native"):
"""
Checks if username exists in the system
:param username: User name
:returns: bool
"""
output = pmb.chroot.root(args, ["getent", "passwd", username],
suffix, output_return=True, check=False)
return len(output) > 0