46

On Ubuntu 12.04, when I sudo -s the $HOME variable is not changed, so if my regular user is regularuser, the situation goes like this:

$ cd
$ pwd
/home/regularuser
$ sudo -s
# cd
# pwd
/home/regularuser

I have abandoned Ubuntu a long time ago, so I cannot be sure, but I think this is the default behavior. So, my questions are:

  1. How is this done? Where is the config?
  2. How do I disable it?

Edit: Thanks for the answers, which clarified things a bit, but I guess I must add a couple of questions, to get the answer I am looking for.

  1. In Debian sudo -s, changes the $HOME variable to /root. From what I get from the answers and man sudo the shell ran with sudo -s is the one given in /etc/passwd, right?
  2. However, on both Ubuntu and Debian the shell given in /etc/passwd for root is /bin/bash. In either system also, I cannot find where the difference in .profile or .bashrc files is, as far as $HOME is concerned, so that the behavior of sudo -s differs. Any help on this?
2
  • You answered part of your own question in a comment on my answer, but I thought I'd put the link unix.stackexchange.com/questions/38175/… here. I think your claim in Q3 is because some people set their profile and rc files to act the same regardless of whether they are in a login shell or not. I think it wildly unlikely that sudo behaves differently between Debian and Ubuntu.
    – msw
    Sep 19, 2013 at 11:38
  • @msw As far as the difference between Debian's and Ubuntu's (12.04) sudo goes, I think that indeed there is a difference by default. However, I don't bet on it, since I am on a box which has been setup by someone else and has been running for quite a while. In any case, for anyone interested, I found security.stackexchange.com/questions/18369/… and bugs.launchpad.net/ubuntu/+source/sudo/+bug/760140.
    – alekosot
    Sep 19, 2013 at 12:00

5 Answers 5

64

Sudo has many compile-time configuration options. You can list the settings in your version with sudo -V. One of the differences between the configuration in Debian wheezy and in Ubuntu 12.04 is that the HOME environment variable is preserved in Ubuntu but not in Debian; both distributions erase all environment variables except for a few that are explicitly marked as safe to preserve. Thus sudo -s preserves HOME on Ubuntu, while on Debian HOME is erased and sudo then sets it to the home directory of the target user.

You can override this behavior in the sudoers file. Run visudo to edit the sudoers file. There are several relevant options:

  • env_keep determines which environment variables are preserved. Use Defaults env_keep += "HOME" to retain the caller's HOME environment variable or Defaults env_keep -= "HOME" to erase it (and replace it by the home directory of the target user).
  • env_reset determines whether environment variables are reset at all. Resetting environment variables is often necessary for rules that allow running a specific command, but does not have a direct security benefit for rules that allow running arbitrary commands anyway.
  • always_set_home, if set, causes HOME to be overridden even if it was preserved due to env_reset being disabled or HOME being in the env_keep list. This option has no effect if HOME isn't preserved anyway.
  • set_home is like always_set_home, but only applies to sudo -s, not when calling sudo with an explicit command.

These options can be set for a given source user, a given target user or a given command; see the sudoers manual for details.

You can always choose to override HOME for a given call to sudo by passing the option -H.

The shell will never override the value of HOME. (It would set HOME if it was unset, but sudo always sets HOME one way or another.)

If you run sudo -i, sudo simulates an initial login. This includes setting HOME to the home directory of the target user and invoking a login shell.

18

Use sudo -H -i instead of sudo -s to get an interactive login root shell:

sudo -H -i
cd
pwd -P  #  /private/var/root  (on Mac OS X 10.6.8)

From man sudo:

-H      The -H (HOME) option sets the HOME environment variable to
        the homedir of the target user (root by default) as
        specified in passwd(5).  By default, sudo does not modify
        HOME (see set_home and always_set_home in sudoers(5)).
1
  • 1
    -i implies -H.
    – x-yuri
    Nov 13, 2019 at 19:09
5

This has little to do with the behavior of sudo and much to do with the difference between a "login shell" and a "non-login shell". The quick fix is

$ sudo -i

as can be seen with:

$ sudo -s
# id
uid=0(root) gid=0(root) groups=0(root)
# echo $HOME
/home/msw
# exit
$ sudo -i
# echo $HOME
/root
# pwd
/root

As noted in the sudo manual:

The -i (simulate initial login) option runs the shell specified by the password database entry of the target user as a login shell. This means that login-specific resource files such as .profile or .login will be read by the shell. If a command is specified, it is passed to the shell for execution via the shell's -c option. If no command is specified, an interactive shell is executed.

5
  • Thanks for the extra details, they clarified things a bit more for me. Guess I have to check the difference between shells. For anyone reading this, on the same situation with me, check this: unix.stackexchange.com/questions/38175/…
    – alekosot
    Sep 19, 2013 at 11:28
  • 1
    No, whether sudo changes HOME or not has everything to do with how sudo is configured. Sep 19, 2013 at 21:40
  • @Gilles: So, how is sudo configured? In /etc/sudoers, there is nothing different between Debian and Ubuntu as far as $HOME is concerned.
    – alekosot
    Sep 20, 2013 at 8:45
  • 1
    @alxs IIRC Debian and Ubuntu have different compile-time defaults. You can override them with the options always_set_home and set_home in sudoers. Sep 20, 2013 at 8:55
  • @Gilles: Thank you. That's exactly the answer I am looking for, both on why this happens and how to revert it. If you don't mind posting it, I will accept it as the answer. I could do it myself, but I don't want to take credit for it.
    – alekosot
    Sep 20, 2013 at 9:05
2

Quite popular way of getting root shell is also using:

 $ sudo su - 
 # id
 uid=0(root) gid=0(root) groups=0(root)
 # pwd
 /root
2
  • I use to use sudo -i -H, but it failed with installing a global npm package from git. With sudo su - it works ! Thank you.
    – Laurent
    Apr 23, 2019 at 8:11
  • Popular does not mean correct Aug 21, 2021 at 20:15
0

To get rid of the different behavior of sudo -s on Ubuntu and Debian respectively, you could use a sudo wrapper (answer to Q4):

sudos() {
   local PATH="$(getconf PATH)" root_homedir
   root_homedir="$(sudo -H sh -c 'printf "%s" "$HOME"')"
   sudo sh -c 'export HOME="$0"; exec sh -i' "$root_homedir"
   return 0
}

sudo -k
sudos
{
logname
whoami
id -un
id -ur
echo "PATH: $PATH"
}
exit
echo "PATH: $PATH"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .