== What it means to become another user on Unix Ignoring things like SELinux for the moment, the basic security state of Unix system calls has always been that root is allowed to become any other UID at will, but no one else is allowed to change their UID or other security attributes (setuid programs then provide an escape hatch from this). But what does it mean to become another user on Unix, beyond just setting your UID? In fact there are a whole series of things that it can mean, some of which you do not necessarily want. Let's make a list: * switching to the user's UID. This is the basic prerequisite of what it means to become another user on Unix, and is done by _setuid()_. * switching your groups to the user's groups, which is done with a combination of _initgroups()_ and _setgid()_. * setting some environment variables like _$HOME_ and _$SHELL_ to values appropriate for the new user. (Most but not all versions of _su_ do this. Versions of _su_ that do not change _$HOME_ can be exciting, especially when combined with shells that read initialization files from _$HOME_.) * clearing various environment variables; in the extreme case, you will clear all environment variables and give yourself a new set of safe values for things like _$PATH_ and so on. (Aggressively scrubbing the environment is generally the default for _sudo_. In general there are any number of environment variables that are very dangerous to leave intact, such as all of the ((LD_*)) variables that influence the behavior of the dynamic loader.) * running the user's shell, either interactively or with _-c ..._ to execute commands. (_su_ normally always runs the user's shell; _sudo_ will often run commands directly without starting the user's shell.) * changing to the user's home directory. * running the user's shell [[as a login shell UsingAlternateShell]]. * allocating a new pseudo-tty as the user and attaching the user's shell and so on to it as a new session. This is generally the domain of things that are making real login sessions, like _sshd_, instead of programs that just become the user. (Note that this list is not in the order that your code wants to actually do these operations. For example, you want to set groups before changing to the other UID because the moment you _setuid()_ to a non-root user you lose the power to set your own groups list.) Many things that become another user deliberately run the the target user's shell even when they just want to run a command. This is done partly so that the user's shell can do any special initialization that, eg, may augment its _$PATH_ and partly so that users with restricted shells can't escape them in various clever ways. However, not everything does this and sometimes running the user's shell is inconvenient. There are [[a surprising number of cases ../sysadmin/SecureUserFileManipulation]] where you want basically the first two only; you want to run a command as a user but in a way such that their environment (their shell, their shell initialization, and so on) is ignored. It's possible to do this with standard commands like _su_ and _sudo_ by carefully reading their manpages and picking exactly the right options, but I find it easier to have a very basic _runas_ program sitting around. (_runas_ only works for root, so it can completely ignore authentication and similar issues.)