I manage a technical group which has responsibility
for administering
corporate systems. Because the systems include a machine
which runs
anonymous access through several different methods,
the group has
to be concerned about who is accessing our systems.
Similarly, we
are periodically concerned about the login/logoff session
activity
which takes place. As our workplace is primarily an
SCO shop, we could
resort to using C2 security and the audit facilities
which exist there.
But we don't.
This article was born out of e-mail with another system
administator
who needs to be able to track login and logoff activity
for later
review. The article discusses several different methods
which could
be used. It does not touch on the use of C2 security,
as a later article
will discuss this environmment in detail.
The process of logging onto a UNIX system starts at
system startup.
All versions of UNIX have a system daemon named init
which
is responsible for starting system daemons and the getty
process.
getty is responsible for printing a login message and
collecting
a user name. Once the user name is collected, getty
executes
login, which then prompts for a password. login validates
the
password/login name combination, and, if the combination
is valid,
creates an entry for the login in the /etc/wtmp file,
then
executes the user's login shell. If the login/password
combination
is incorrect, login asks for a login name again. (For
more
information on the login process, including password
validation, see
"How UNIX Password Controls Work," Sys Admin,
vol.
1, no. 1, May/June 1992).
An understanding of the options and capabilities of
the who command
is essential to this discussion, largely because of
its interaction
with the /etc/wtmp file (which will be discussed in
detail
later). In this section, I describe the various options
of the who
command and provide example output.
The who command provides the following options (see
Figure 1 and Figure 2 for more information on these options):
The /etc/wtmp file is a historical record of all of
the login
activity on the system. In fact, a number of events
are included in
this file, and these can be listed using the who command.
Listing 1 shows the structure associated with the /etc/wtmp
file.
Login process -- When a getty process
is waiting for a login to occur, a record is written
to indicate the
state of the getty process.
The information is stored in this file in binary form
using the structure shown in Listing 1. As a result, the easiest way to
look at the contents of /etc/wtmp is through the who command.
Logging in and out with the Bourne and Korn Shells
When a user logs in to a UNIX machine with a login shell
of /bin/sh
or /bin/ksh, the system file /etc/profile is executed
before the file .profile in the user's $HOME directory.
Since /etc/profile is executed for all users, you can
put lines
in this file to record the login. For example
echo "LOGIN :`logname`:`tty`:`date`" > /usr/adm/logins
will record the login. The information included is the
login name, the tty where the login took place, and
the date.
The command above would generate the following output
in the file
/usr/adm/logins:
chare:/dev/w2:Sun Jun 13 17:48:16 EST 1993
Unlike the C shell, the Bourne and Korn shells have
no
built-in mechanism for tracking logouts. However, it's
possible to
fool the shell by having it trap the signal which signifies
a logout,
which is signal 0. The mechanism for accomplishing this
is the shell's
built-in signal handler. The command is trap, and the
syntax
used is
trap "command to execute" signal ...
Inserting this command in /etc/profile, as follows,
trap "/usr/local/checkout `logname` `tty`" 0
causes the command checkout to be run a signal
0 is received. At this point you may be wondering why
I don't use
a sub-shell. Signal handlers are not passed to child
processes,
so they will not see this handler. A good approach is
to set
the user's login name to a variable such as LOGNAME
and the
terminal being used to a variable named TTY. This increases
the speed at which the logout is executed.
So what is /usr/local/checkout? It could be as simple
as the
line used in /etc/profile for logging in, with a couple
of
changes:
echo "LOGOUT:$LOGNAME:$TTY:`date`" > /usr/adm/logins
Listing 2 shows a sample /etc/profile file with
code added to support the login and checkout scripts.
Listing 3 shows the checkout program, while Figure 3
shows
the output of the login and logout programs in /usr/adm/logins.
Logging in and out with the C shell
For C shell users, the same approach is applicable.
The primary difference
to note is that /etc/profile is not executed, but /etc/cshrc
is. The same syntax shown above for the /etc/profile
applies
here; the one minor difference is that it would be prudent
to include
the '!' after the '>' signs. This disables the no-clobber
feature of the C shell, where it would normally be an
error to append
to a file if the file didn't already exist. An example
is
echo "LOGIN :`logname`:`tty`:`date`" >! \
/usr/adm/logins
You can accomplish this through the use of the .logout
file in the user's $HOME directory. This is somewhat
inefficient
as it means duplicating a small amount of information
across all of
the users on the system. The amount of information isn't
really significant,
but it is something to be considered.
Again, the code fragment shown below, which is a variation
of the
/usr/local/checkout program, can be used for the .logout
file.
echo "LOGOUT:$LOGNAME:$TTY:`date`" >! \
/usr/adm/logins
Again, note that the '!' is included to prevent
problems with the no-clobber variable in the C shell.
Report Generators
The only reason for collecting information is so that
you can look
at it later. The shell script shown in Listing 4 takes
the information
from /usr/adm/logins and presents it in a meaningful
fashion.
This shell script is a simple one. It sorts /usr/adm/logins
before processing, using the sort sequence
1. username
2. direction (LOGIN/LOGOUT)
3. tty
I chose this sequence to maintain the connectivity of
logins to logouts
where possible. Sample output of the program in Listing
4 is in Figure 5.
This isn't the most complex reporting program in
the world, but
it illustrates the principle.
Conclusions
While there are many ways of tracking login activity
-- including
the methods described here, as well as process accounting,
security
system auditing, and other services provided by individual
vendors
-- there are a few specific things to keep in mind.
In order for the implementation discussed to be of value,
the /usr/adm/logins
file must be world writeable. This means that anyone
could edit the
file to change the contents. Furthermore, there are
situations where
the trap will not be set up and executed when the user
logs out.
One such case is with the AT&T UNIXPC and 3B1 series
of computers,
which have a graphical interface. This interface doesn't
work like
a shell, and therefore will not execute the trap set
up in /etc/profile.
In these cases, there will be no corresponding logout
record, as illustrated
in Figure 4.
Some readers may ask why I didn't simply have /etc/profile
execute, run a child shell for the user's interactive
session, and,
when the user exits with Control D, continue with /etc/profile,
so that the logout information would be recorded. The
problem here
is that this would create an additional (and unncessary)
process on
the system. And while such a process would not consume
much in the
way of system resources, it would occupy a process slot
in the process
table, which can be a problem if you are losing 25 or
more process
slots for these activities. It might become necessary
for the system
administrator to make the process table bigger, and
thereby increase
the size of the kernel in RAM, thus decreasing the amount
of usable
RAM for user processes.
For more information on system monitoring, see the articles
"Getting
the Info: u386mon" in Sys Admin, vol. 1, no. 3
(Sept/Oct
1992), and "Getting the Info: sar" in Sys
Admin, vol.
1, no. 4 (Nov/Dec 1992). For further information on
Shell Programming,
see your system documentation, and for a specific discussion
of a
login session billing program, see UNIX/World, October
1986.
About the Author
Chris Hare is the Technical Services Manager for
Choreo Systems, Inc.
He has worked in the UNIX environment since 1986 and
in 1988 became one of
the first SCO authorized instructors in Canada. He teaches
UNIX introductory,
system administration, and programming classes. His
current focus is on
networking, Perl, and X. Chris can be reached at chare@choreo.ca,
or
chare@unilabs.org, which is his home.