Bash – sudo not executing bashrc as expected

.bash-profilebashlinuxprofilesudo

Overall issue is when I log in, my prompt appears correctly formatted as per the /etc/bashrc but when I sudo to another user using bash, the prompt gets fubar'd.

Essential formatting in the /etc/bashrc

PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'

…and…

prompt_host=`/bin/hostname`

Sequence:

I log into my terminal as myuser. My prompt is properly formatted as matching the /etc/bashrc above:

myuser@the.hostname.fully.qualified pwd :

Though the above implies my default shell program appears to be bash, I believe I'm using sh:

echo $SHELL     <---not very meaningful but I expect someone will ask me to run this
/bin/sh

ps -p `echo $$`
  PID TTY          TIME CMD
 7105 pts/2    00:00:00 sh     <---which looks to be an interactive shell (no dash)

ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
72338     9321  9320  0 01:07 pts/3    00:00:00 -sh   <---or is it a login shell????

./filethatsnotthere.sh
-sh: ./filethatsnotthere.sh: No such file or directory

And last, but not least…

getent passwd myuser
myuser:x:72338:25000:My Name:/home/myuser:/bin/sh

Also, it's apparent that the /etc/profile is being sourced because:

echo $prompt_host
the.hostname.fully.qualified

So looks like sh and that the /etc/profile is being sourced. BUT this confuses me…

 ls -l `which sh`
lrwxrwxrwx. 1 root root 4 Jan 12  2018 /bin/sh -> bash

…sigh…But even if we go with the theory that I'm using sh, I then sudo to newuser using bash. newuser has a profile setup as newuser .bash_profile which sources newuser .bashrc which sources the /etc/bashrc.

But the prompt for newuser isn't working right and it's apparent that none of the newuser profile is run. It totally loses the hostname in the prompt

sudo -u newuser bash
newuser@ pwd         <---no hostname

I know NONE of the newuser profile is run because I put echo statements in them to confirm when they're run, and they don't display. Even so, I've confirmed that newuser is truly running bash:

ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
newuser  11717 11715  0 03:47 pts/1    00:00:00 bash

ps -p `echo $$`
  PID TTY          TIME CMD
11717 pts/1    00:00:00 bash

./filethatsnotthere.sh
bash: ./filethatsnotthere.sh: No such file or directory

The /etc/profile is not being run (which makes sense since this is an interactive, not login, shell):

echo $prompt_host
<crickets....>

BUT – neither is newuser's startup files in the /home/newuser directory…So, if I'm using sudo to a user with command bash, why isn't that user's bash profile files being sourced? Since it's an interactive shell, even though the /etc/profile is not directly being sourced I would still expect the newuser's files to be run.

Best Answer

sudo can be configured to set $HOME to match the new user when switching users, or not to. In your case, it appears it is set to not switch $HOME. That can be useful when you want to switch to user accounts that are dedicated to specific service applications, but still want to keep using your personal shell configuration and other settings.

And ~/.bashrc is actually just a shorthand for $HOME/.bashrc.

So when you do sudo -u newuser bash, sudo switches the username to newuser but $HOME is still set to /home/myuser.

When bash attempts to execute ~/.bashrc, it has a slight problem: as newuser, it might have no access to read /home/myuser/.bashrc unless you have specifically granted that access. If you haven't, that is probably why .bashrc is getting skipped. Because $HOME is still set to /home/myuser, there will be no attempt to execute /home/newuser/.bashrc.

If you want sudo to set HOME=/home/newuser, you can:

  • use the -H option with the sudo command: sudo -Hu newuser bash
  • or add Defaults>newuser always_set_home to your sudoers file to automatically set the home directory when switching to newuser only
  • or add Defaults:myuser always_set_home to sudoers file to automatically set the home directory to match the new identity when myuser is running any sudo commands
  • or add Defaults always_set_home to sudoers file to force this behavior for all sudo commands on the system. (Some Linux distributions have this enabled by default.)

If you don't especially want to switch the home directory when switching users, then you'll need to make sure the new user can read your personal shell startup files instead.

The minimal permissions you'd need to allow for sudo -u newuser bash to run /home/myuser/.bashrc are:

  • a search permission to /home/myuser
  • a read permission to /home/myuser/.bashrc

If there is no convenient user group that would be common to both myuser and newuser, and ACLs are not available (i.e. traditional Unix-style permissions only), this would be the traditional way to do it:

chmod 711 /home/myuser          # i.e. directory permissions drwx--x--x
chmod 644 /home/myuser/.bashrc  # i.e. file permissions      -rw-r--r--

If ACLs are available for the filesystem containing your home directory, you could do this instead to grant the minimal necessary access:

setfacl -m u:newuser:x /home/myuser
setfacl -m u:newuser:r /home/myuser/.bashrc

If the permissions of the home directory were initially drwx------, after this command the permissions to /home/myuser would look like drwx--x---+. To check the complete ACL, use getfacl:

$ getfacl /home/myuser
getfacl: Removing leading '/' from absolute path names
# file: home/myuser
# owner: myuser
# group: myuser
user::rwx
user:newuser:--x
group::---
mask::--x
other::---
Related Question