Sometimes, one user must assume the identity of another. For example, you might sit down at a friend's terminal and want to access one of your protected files. Rather than forcing you to log your friend out and log yourself in, UNIX gives you a way to change your user ID temporarily. It is called the su command, short for "substitute user." su requires that you provide the password of the user to whom you are changing.
For example, to change yourself from tim to john , you might type:
% whoami tim % su john password: fuzbaby % whoami john %
You can now access john 's files. (And you will be unable to access tim 's files, unless those files are specifically available to the user john .)
Processes on UNIX systems have at least two identities at every moment. Normally, these two identities are the same. The first identity is the real UID. The real UID is your "real identity" and matches up (usually) with the username you logged in as. Sometimes, you may want to take on the identity of another user to access some files or execute some commands. You might do this by logging in as that user, thus obtaining a new command interpreter whose underlying process has a real UID equal to that user.
Alternatively, if you only want to execute a few commands as another user, you can use the su command, as described above, to create a new process. This will run a new copy of your command interpreter (shell), and have the identity (real UID ) of that other user. To use the su command, you must either know the password for the other user's account, or you must currently be running as the superuser.
There are times when a software author wants a single command to execute with the rights and privileges of another user - most often, the root user. In a case such as this, we certainly don't want to disclose the password to the root account, nor do we want the user to have access to a command interpreter running as root . UNIX addresses this problem through the use of a special kind of file designation called setuid or SUID . When a SUID file is run, the process involved takes on an effective UID that is the same as the owner of the file, but the real UID remains the same. SUID files are explained in the following chapter.
Some versions of UNIX have a third form of UID : the saved UID . In these systems, a user may run a setuid program that sets an effective UID of 0 and then sets some different real UID as well. The saved UID is used by the system to allow the user to set identity back to the original value. Normally, this is not something the user can see, but it can be important when you are writing or running setuid programs.
UNIX also has the analogous concepts of effective GID , real GID , and setgid for groups.
Some versions of UNIX also have session IDs, process group IDs , and audit IDs . A session ID is associated with the processes connected to a terminal, and can be thought of as indicating a "login session." A process group ID designates a group of processes that are in the foreground or background on systems that allow job control. An audit ID indicates a thread of activity to be indicated as the same in the audit mechanism. We will not describe any of these further in this book because you don't really need to know how they work. However, now you know what they are if you encounter their names.
Typing su without a username tells UNIX that you wish to become the superuser. You will be prompted for a password. Typing the correct root password causes a shell to be run with a UID of 0. When you become the superuser, your prompt should change to the pound sign (#) to remind you of your new powers. For example:
% /bin/su - password: k697dgf # whoami root #
When using the su command to become the superuser, you should always type the command's full pathname, /bin/su . By typing the full pathname, you are assuring that you are actually running the real /bin/su command, and not another command named su that happens to be in your search path. This method is a very important way of protecting yourself (and the superuser password) from capture by a Trojan horse. Other techniques are described in Chapter 11 . Also see the sidebar in the section the sidebar "Stealing Superuser" later in this chapter.
Notice the use of the dash shown in the earlier example. Most versions of the su command support an optional argument of a single dash. When supplied, this causes su to invoke its sub-shell with a dash, which causes the shell to read all relevant startup files and simulate a login. Using the dash option is important when becoming a superuser: the option assures that you will be using the superuser's path, and not the path of the account from which you su 'ed.
To exit the subshell, type exit or press control-D.
If you use the su command to change to another user while you are the su-peruser, you won't be prompted for the password of the user who you are changing yourself into. (This makes sense; as you're the superuser, you could as easily change that user's password and then log in as that user.) For example:
# su john % whoami john %
Once you have become the superuser, you are free to perform whatever system administration you wish.
Using su to become the superuser is not a security hole. Any user who knows the superuser password could also log in as superuser; breaking in through su is no easier. In fact, su enhances security: many UNIX systems can be set up so that every su attempt is logged, with the date, time, and user who typed the command. Examining these log files allows the system administrator to see who is exercising superuser privileges - as well as who shouldn't be!
If you are the system administrator, you should be careful about how you use the su command. Remember, if you su to the superuser account, you can do things by accident that you would normally be protected from doing. You could also accidentally give away access to the superuser account without knowing you did so.
As an example of the first case, consider the real instance of someone we know who thought that he was in a temporary directory in his own account and typed rm -rf *. Unfortunately, he was actually in the /usr/lib directory, and he was operating as the superuser. He spent the next few hours restoring tapes, checking permissions, and trying to soothe irate users. The moral of this small vignette, and hundreds more we could relate with similar consequences, is that you should not be issuing commands as the superuser unless you need the extra privileges. Program construction, testing, and personal "housecleaning" should all be done under your own user identity.
Another example is when you accidentally execute a Trojan Horse program instead of the system command you thought you executed. (See the sidebar later in this chapter.) If something like this happens to you as user root , full access to your system can be given away. We discuss some defenses to this in Chapter 11 , but one major suggestion is worth repeating: if you need access to someone else's files, su to that user ID and make the accesses as that user rather than as the superuser.
For instance, if a user reports a problem with files in her account, you could su to the root account and investigate, because you might not be able to access her account or files from your own, regular account. However, a better approach is to su to the superuser account, and then su to the user's account - you won't need her password for the su after you are root . Not only does this method protect the root account, but you will also have some of the same access permissions as the user you are helping, and that would help you find the problem sooner.
On some versions of Berkeley-derived UNIX , a user cannot su to the root account unless the user is a member of the process group wheel - or any other group given the group ID of 0. For this restriction to work, the /etc/group entry for group wheel must be non-empty; if the entry has no usernames listed, the restriction is disabled, and anyone can su to user root if they have the password.
Some versions of su also allow members of the wheel group to become the superuser by providing their own passwords instead of the superuser password. The advantage of this feature is that you don't need to tell the superuser's password to a user for them to have superuser access - you simply have to put them into the wheel group. You can take away their access simply by taking them out of the group.
Some versions of System V UNIX require that users specifically be given permission to su . Different versions of UNIX accomplish this in different ways; consult your own system's documentation for details, and use the mechanism if it is available.
Another way to restrict the su program is by making it executable only by a specific group and by placing in that group only the people who you want to be able to run the command. For information on how to do this, see "Changing a File's Permissions" in Chapter 5 .
Most versions of the su command log failed attempts. Older versions of UNIX explicitly logged bad su attempts to the console and in the /var/adm/messages file.[11] Newer versions log bad su attempts through the syslog facility, allowing you to send the messages to a file of your choice or to log facilities on remote computers across the network. (Some System V versions log to the file /var/adm/sulog in addition to syslog, or instead of it.)
[11] Many UNIX log files that are currently stored in the /var/adm directory have been stored in the /usr/adm directory in previous versions of UNIX.
If you notice many bad attempts, it may well be an indication that somebody using an account on your system is trying to gain unauthorized privileges: this might be a legitimate user poking around, or it might be an indication that the user's account has been appropriated by an outsider who is trying to gain further access.
A single bad attempt, of course, might simply be a mistyped password, someone mistyping the du command, or somebody wondering what the su command does.[12]
[12] Which of course leads us to observe that people who try commands to see what they do shouldn't be allowed to run commands like su once they find out.
You can quickly scan the /var/adm/messages file for bad passwords with the grep command:
% grep BAD /var/adm/messages BADSU 09/12 18:40 - pts/0 rachel-root
Good su attempts look like this:
% grep + /var/adm/sulog SU 09/14 23:42 + pts/2 simsong-root SU 09/16 08:40 + pts/4 simsong-root SU 09/16 10:34 + pts/3 simsong-root
It would appear that Simson has been busy su 'ing to root on September 14th and 16th.
The /var/adm/messages log has a different format on computers running Berkeley UNIX :
% grep su: Sep 11 01:40:59 bogus.com su: ericx to root on /dev/ttyu0 Sep 12 18:40:02 bogus.com su: BAD su rachel on /dev/ttyp1
In this example, user rachel tried to su on September 12th and failed. This is something we would investigate further to see if it really was Rachel.
On older versions of UNIX , the su command was frequently used in the crontab file to cause programs executed by cron to be run under different user IDs. A line from a crontab file to run the UUCP uuclean program (which trims the log files in the uucp directory) might have had the form:
0 4 * * * su uucp -c /usr/lib/uucp/uuclean
This use of su is now largely obsolete: the few systems that still use a single crontab file for all users now allow the username to be specified as the sixth argument on each line of the crontab file:
0 4 * * * uucp /usr/lib/uucp/uuclean
Most versions of UNIX now use a version of the cron system that can have a separate crontab file for each user, and there is no need to specify the username to use. Each file is given the username of the user for whom it is to be run; that is, cron commands to be run as root are placed in a file called root , while cron commands to be run as uucp are placed in a file called uucp . These files are often kept in the directory /usr/spool/cron/crontabs .
Nevertheless, you can still use the su command for running commands under different user names. You might want to do this in some shell scripts. However, check your documentation as to the proper method of specifying options to be passed to the command via the su command line.