What's the difference between login as user and changing users using su through root?

9,383

SSH starts a login shell. su, by default does not.

In particular, this means that the ~/.profile (or similar file) for that user is not sourced. So changes made in ~/.profile won't take effect. It might also be the case that:

  • even if you start a login shell, different changes were made in root's ~/.profile, which might pollute the user's environment.
    • /etc/profile and /etc/profile.d/* may apply settings differently for different users (not by default, though)
  • there might be different settings for different users in SSH configuration.
  • PAM configuration is different. For example, /etc/pam.d/ssh has:

    session    required     pam_env.so user_readenv=1 envfile=/etc/default/locale
    

    whereas /etc/pam.d/su has:

    session       required   pam_env.so readenv=1 envfile=/etc/default/locale
    

    This means SSH loads ~/.pam_environment, but su doesn't. This is a big one, since ~/.pam_environment is the shell-independent place for environment variables, and it is applied if you login from the GUI, the TTY or SSH.

To start a login shell, run either of:

su - <username>
sudo -iu <username>

Example:

# su muru -c 'sh -c "echo $HOME $PATH"'
/home/muru /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
# su - muru -c 'sh -c "echo $HOME $PATH"'
/home/muru /home/muru/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
# sudo -iu muru sh -c 'echo $HOME $PATH'
/home/muru /home/muru/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# sudo -u muru sh -c 'echo $HOME $PATH'
/root /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# ssh muru@localhost 'echo $HOME $PATH'
/home/muru /home/muru/devel/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Even with SSH, if you run a command instead of starting a shell, a login shell won't be run (note the absence of ~/bin in the SSH test, which is present in su - and sudo -i). To get the true result, I will run my shell as a login shell:

# ssh muru@localhost '$SHELL -ilc "echo \$HOME \$PATH"'
/home/muru /home/muru/bin:/home/muru/devel/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

This is also why sudo su and sudo -s are crappy ways of getting a root shell. Both these ways are polluted by the environment.


Related:

Share:
9,383

Related videos on Youtube

Miguel Corti
Author by

Miguel Corti

I'm nearly finishing my graduation in Computer Engineering at PUC-Rio and work (mostly) as the Backend Developer at Trampolin.

Updated on September 18, 2022

Comments

  • Miguel Corti
    Miguel Corti over 1 year

    When you have a server of some sort you can access it through, e.g., ssh user1@ip and you can also do ssh root@ip to go to your root user with su priveleges and then go to su user1. In my thinking both those ways should lead me to the same user environment(in this case, "user1"), but in my actual experience it does not, cause in ssh user1@ip there's things installed that in su user1 there isn't.

    Why is that?

  • Videonauth
    Videonauth almost 8 years
    Seems i should be awake before taking on questions :) your answer is wonderful and mine missed to target the proper answer. Well done +1
  • Mr.President
    Mr.President almost 8 years
    Ah ok, sorry ... I was actually wondering why everyone was going into technical detail, I guess I misread your intention.