How to: Please sudo, do _not_ setup any environment, especially $SUDO_USER

environment-variablessudo

I want to start a process as another uid and it should not need any information from $(env), so I strip the environment prior to the sudo -u powerlessuser /bin/processCmd, that is I run this

env -i sudo -u powerlessuser /bin/processCmd

it turns out sudo thinks it is necessary to repopulate the environment, which I would like to ask it not to do. There is for instance $SUDO_USER set which even tells the powerlessuser's /bin/processCmd about me(tm) that called the command, which I find very indiscrete. Any help?

It is as I figured also possible to use env -i stripping after the sudo, i.e. do this:

sudo -u powerlessuser /usr/bin/env -i /bin/processCmd

which solves the problem somewhat, yet I would really like to know if there is a way to make sudo not add any information in the first place, I browsed man 8 sudo in which I found documentation that sudo adds environment and which, but no help how to make sudo not do that

@terdon♦: I want all environment variables cleaned that are not necessary. I am unable to tell which environmental variables are necessary but just to stick to the question, I have not found the reason why $SUDO_USER would be needed by a process to be called as an unpriveledged user. Therefore I would be satisfied to know how to tell sudo not to leak SUDO_USER

Update – xy-problem issue

As much as I am very interested in avoiding anything of the kind of a xy-problem, I fear it is not the case here. That is because, I do not have actually a different problem as the one stated in the question, namely that searching a way to make sudo not do something, which I can reasonably expect: Sudo get an cleaned up environment and should at best not add stuff to it, i.e. $SUDO_USER. For this reason I am rather very convinced not to have any other problem, since I have already a cure to that issue that sudo leaves me with, i.e. I can do:

sudo -u powerlessuser /usr/bin/env -i /bin/processCmd

which "cleans up after sudo", so in no way is my problem something else, because using the subsequent env -i solved any problem there. The only thing I ask is for knowing if there would have been indeed a way like
sudo --empty-env which then would spawn the new process with an emptied environment, one that at least would not tell $SUDO_USER which uid ran the original sudo.

For all that showed interest in helping me with this question, I like to thank them! I also leave some time, maybe there is such a --empty-env switch possibility. If not maybe somebody that is inside of sudo can tell, i.e. with reference to the sources that such a task is impossible, as sudo cannot but put that undesired $SUDO_USER inside.

Again no xy-problem, for the fact, that it is not really a problem to start with, i.e I do not suffer from the shortcomings of sudo here, as it is solved by a subsequent env -i, which in "unix philosophy" is the one thing that env -i does well, i.e. clean the environment. I should maybe not even have expected any reasonable behavior from sudo there, as sudo has a different one-purpose, which is not concerned about environment variables leaking. Even though, the fact that sudo does offer some flags relating to environment variables misleads into thinking it would deal with environment variables well.

Best Answer

If the tool does not do what you want, you can improve it using a wrapper script. I use this script (noenv) to keep build environments clean. Using it like

sudo -u powerlessuser noenv /bin/processCmd

would do what you're asking. (The script should be in the standard path, otherwise you have to provide it path in the command).

Script:

#!/bin/sh
# $Id: noenv,v 1.3 2014/05/10 22:43:32 tom Exp $
# trim the environment to minimal (PATH may still be long...)
env | sed -e 's/=.*//' -e '/^[  ].*/d' | \
while true
do
    read value
    if test -z "$value" ; then
        # honor assignments to variables in the parameter list
        while test $# != 0
        do
            case "x$1" in
            *=*)
                eval $1
                name=`echo "$1"|sed -e 's/=.*//'`
                export $name
                shift 1
                ;;
            *)
                break
                ;;
            esac
        done
        exec "$@"
        break
    fi
    case "$value" in
    HOME|PATH|USER|_|SHLVL|TMPDIR|LOGNAME)
        ;;
    *\ *|*\(*|*\)*|*\!*)
        #echo "...skipping $value"
        ;;
    *)
        #echo value:"$value"
        unset "$value"
        ;;
    esac
done

To clarify, I did not write this using /usr/bin/env, because some of the systems on which I was building did not have a POSIX feature which the question mentioned: the -i option. Those are old BSD systems, including SunOS 4 and HPUX 10 (checking my memory against the manual page for "env" on FreeBSD).

The script, by the way, trims out multi-line values (but the only one you might encounter is TERMCAP, and that only on very old machines). The second sed-expression is supposed to be a range with tab and space.

For POSIX (which you probably are more interested in), you could do something that uses the feature to pass in selected values from the parent environment, e.g.,

env -i foo="bar"

and so both are customizable. For a large set of variables, that can be clumsy, and a script is a better choice.

sudo disapproves of TERMCAP in any case. That is on a (long) list of variables which it helpfully removes from the environment.

sudo insists on setting certain variables. Reading the source plugins/sudoers/env.c, you will see this chunk near the end of rebuild_env:

/* Add the SUDO_USER, SUDO_UID, SUDO_GID environment variables. */
CHECK_SETENV2("SUDO_USER", user_name, true, true);
snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int) user_uid);
CHECK_SETENV2("SUDO_UID", idbuf, true, true);
snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int) user_gid);
CHECK_SETENV2("SUDO_GID", idbuf, true, true);

debug_return_bool(true);

that is, just before the (only) successful return from that function, it sets its own variables, using its own values.