Determining home dir of a user

chroothomeusers

I need to know how home directory for a linux user is determined. Everyone's answer would be "hey, look at /etc/passwd and find it out". But this seems not to be always correct. Look at this:

$ whoami
test
$ cat /etc/passwd
test:x:2000:2000::/home/test:/bin/bash  (relevant line)
$ echo ~
/root
$ cd
bash: cd: /root: No such file or directory

I really have no idea what is going on. It is a subsystem which I entered as root by chroot --userspec=test path/to/subsystem/ /bin/bash. Does anyone know what this is and how to fix it so that ~ expands to /home/test and cd works as expected?

Best Answer

Looking up in /etc/passwd is correct for local user accounts (unless the system administrator has gone out of their way to make things difficult). The correct general answer is to look up in the user database that contains the user account, e.g. LDAP. Most modern systems use NSS to list user databases, so check /etc/nsswitch.conf on your system if you think there might be non-local accounts.

From an application's perspective, the correct answer is that the home directory is whatever the HOME environment variable says.

Login programs (login, sshd, X display managers, etc.) normally set the HOME environment variable to the home directory of the user that's logging in. “High-level” user change programs such as su and sudo change HOME to (with sudo, it depends on the configuration and the command line options). So normally, the definition for “home directory of the current user” matches with the combination of “user's home directory” and “current user”.

But chroot doesn't change HOME, so your session in the chroot inherits from the HOME environment variable in the parent process, which is unsurprisingly /root. In bash, like any other shell, ~ expands to the value of HOME, defaulting to the user database lookup if HOME is not set.

Solution: unset HOME.

env -u HOME chroot --userspec=test path/to/subsystem/ /bin/bash
Related Question