27

Is there any way to specify that sudo should preserve certain environment variables for specified commands only? For some purposes I'd like my $HOME env. variable preserved when I run certain commands. For other purposes and other commands, I want it reset. Can this be done with /etc/sudoers?

Edit:

Thank you for the answers. I wonder if I might ask a follow-up question, which is "Why, then, does this not work?"

In the example I'm trying to get working, I want sudo nano to read my $HOME/.nanorc. If I use this:

Defaults:simon env_keep=HOME

it works perfectly. If I use this:

Defaults!/bin/nano env_keep=HOME

or this:

Cmnd_Alias      NANO = /usr/bin/nano,/bin/nano,/bin/rnano
Defaults!NANO   env_keep=HOME

it's not working at all. Any suggestions as to why? (I'm on Debian testing, btw.)

(Note: I don't think it's nano specific, btw -- I can reproduce the behaviour with a one-line bash script that simply echos $HOME).

simon
  • 1,508
  • 1
    Instead of trying to get nano run through sudo to use the same config file, use sudoedit instead. sudoedit will run copy the contents of a file to a tmp file and run the editor of your choice as your user, when the editor exits it will check if you changed anything and if so replace the original with the edited one. You can select which editor you want it to run by setting the $EDITOR or $VISUAL` env vars. – Arrowmaster May 17 '11 at 17:31
  • @Arrowmaster -- thanks, that seems like a better approach than the one I was messing around with. Since I'm already wrapping sudo with a function of my own, I've simply added a if [ "$1" == "$EDITOR" ]; then block and am now calling sudoedit instead :) – simon May 18 '11 at 02:21
  • Be careful with this. If the individual command is written in Python or a shell script this might be exploited to gain a root shell. Python looks in $HOME/.local/lib/python/site-packages For a shell script, pass -f and -p (protected for ksh/zsh). – okapi Dec 17 '21 at 15:10

3 Answers3

31

To override env_keep only for /path/to/command (when invoked through any rule, by any user) and for the user joe (no matter what command he is running):

Defaults!/path/to/command env_keep=HOME
Defaults:joe env_keep=HOME

You can use -= or += to remove or add an entry to the env_keep list.

  • brilliant, thank you. I couldn't find a proper example of that syntax. Now that you spell it out for me, I can see how I should have worked that out from the man page, and I feel slightly foolish. No doubt this answer will help others, too, though. – simon May 17 '11 at 07:26
  • 1
    @simon: Don't feel foolish, I too find the syntax description in the sudoers man page hard to work out from the formal description and the examples easier to locate if you already know how to write them. – Gilles 'SO- stop being evil' May 17 '11 at 08:19
  • hmm - perhaps I spoke to soon. Now that I try this, I can't actually get it to work. Can I trouble you to take a look at my revision? – simon May 17 '11 at 09:46
  • 1
    @simon: My guess is that you also have an entry that lets you do everything and doesn't have that env_keep setting (simon ALL = ALL). Sudo uses the last matching entry. – Gilles 'SO- stop being evil' May 17 '11 at 11:17
  • Beware, if secure_path is set, you will also have to add Defaults:joe !secure_path – Jistanidiot Apr 20 '16 at 14:40
8
Cmnd_Alias      PBUILDER = /usr/sbin/pbuilder,/usr/sbin/cowbuilder
Defaults!PBUILDER       env_keep+=HOME

Those lines are from my own /etc/sudoers to correct the issue that pbuilder looks in $HOME for its user config file but must be run as root (moving it to /root kinda defeats the purpose of having both a system and a user config file).

Arrowmaster
  • 1,684
  • yeah, that's a very similar use case to the one I had in mind, thanks! – simon May 17 '11 at 07:24
  • do you have any idea why the examples in my revision don't seem to work? – simon May 17 '11 at 09:46
  • @simon sudo is very picky about the order of entries in its config, later entries will overwrite previous ones. There could be some conflict like that in your config. – Arrowmaster May 17 '11 at 17:35
1

man sudoers:

   env_reset       If set, sudo will reset the environment to only contain
                   the LOGNAME, SHELL, USER, USERNAME and the SUDO_*
                   variables.  Any variables in the caller’s environment
                   that match the env_keep and env_check lists are then
                   added.  The default contents of the env_keep and
                   env_check lists are displayed when sudo is run by root
                   with the -V option.  If the secure_path option is set,
                   its value will be used for the PATH environment
                   variable.  This flag is on by default.

Therefore yes, you can do that using env_reset, env_keep and env_check in your /etc/sudoers.