Two Handy AIX Tools: The Failed Login Report and lptran
Jeff Courington
AIX is a very distinctive implementation of UNIX, with
its own strengths
and weaknesses. In the course of administering an AIX
system, I've
developed a couple of tools that you might also find
useful. The first
is a failed login report generator, which allows you
to track failed
logins on the system. The second is lptran, a utility
that
allows you to move print jobs from one queue to another
(a functionality
mysteriously missing from AIX).
A Failed Login Report for AIX
Among other duties, system administrators must teach
the basic skills
needed to use the system. The first of these skills
is logging into
the system: first you enter your login name, then you
enter your password.
I thought this was a simple procedure until I looked
at the failure
records contained in AIX's /etc/security/failedlogin
file.
Taking myself as an average user, I was suprised to
find that over
the last year and a half I had failed the login process
205 times.
Remember that the failedlogin file can only track logins
with
correct login names and incorrect passwords. All other
entries are
assigned to the login UNKNOWN. I found that on my system
the high
number was 698. It then occurred to me that a report
on failed logins
could be a useful system administration tool. Such a
tool would draw
its data from the failedlogin file.
The failedlogin File
For successful logins, entries are made in the two system
files /etc/utmp
and /usr/adm/wtmp. The who command uses the /etc/utmp
file to show the current users on the system, while
the /usr/adm/wtmp
file contains system accounting records for connections.
If the login
process fails, the file that gets updated is
/etc/security/failedlogin.
The failedlogin file records the failed login attempts
in sequential
order. The AIX manual, Elements Of AIX Security: R3.1
(Doc # GG42-3622-1),
warns that this file should not be edited. To recover
disk space,
however, it can be deleted to allow the system to recreate
it. The
utmp.h header file defines the structure for the utmp
record as shown in Figure 1.
Figure 2 shows the special values the ut_line variable
can
have if it is accounting for something other than a
login, while Figure 3
lists the possible values for ut_type.
The utmp structure contains three other structures:
ut_exit,
ut_time, and ut_termio. The ut_exit structure
contains the process termination status and the exit
status. These
fields tell something about why and how the process
was completed.
The ut_time structure records the login time of the
process.
The ut_termio structure records the initial terminal
settings
as shown by the stty -a command.
Although some of these entries are not very relevant
for a failedlogin
file, they are included so that the record will match
the entries
in the /etc/utmp file, which keeps the current user
information.
AIX users are probably familiar with the bug in the
who program
that shows ghost users on the system (a pseudo-terminal
looks like
it is logged in even though it really is not). By searching
through
the /etc/utmp file and only showing logins with the
ut_type
equal to USER_PROCESS, you can get a real list of who
is on
the system.
Program Implementation
The program in Listing 1 creates a report from the failedlogin
file. Lines 27-30 check to see if the user wants the
help for the
flogin program to be printed. If not, the program checks
to
see whether the report should cover all users or a specific
user.
The meat of the program is in the print_users procedure,
which
first opens the failedlogin file at line 65. It checks
user_name
against the string NOBODY on line 69 to see if the report
should
print the user name as a header. It uses this same test
on line 74
to decide whether to print all of the entries or to
check the entry
against user_name string. Line 71 uses fread to get
records from the failedlogin file. Since the records
are stored
using the structure utmp each read is for a record the
size
of this structure. The while loop consists of various
tests
that must be performed to generate the final report.
Lines 76 and
81 convert the ut_time variable by using the localtime
and asctime functions. The ut_time variable is stored
in seconds since the epoch. The localtime function call
converts
this into a tm structure, which asctime then converts
to the format that we expect from the date command.
Lines 84
and 85 finish the loop and print the number of failed
logins. Line
86 prints a form feed, Octal 14, so that the printer
will stay
in alignment and return the number of users counted.
When I run the report, I usually use a small shell script
to format
the printout by user:
lsuser -a ALL|cut -f1 -d" "|xargs \
-i% flogin -u %
Figure 4 shows sample output from the program.
Security Benefits
The failed login report can be useful for system security.
If you
have a modem on the system, you can use the report to
find out if
someone has been trying to log into the system via the
modem. Since
the /usr/adm/wtmp file only contains successful logins,
the
accounting reports will not show failed attempts at
breaking into
the system. And it is usually only a matter of time
before these failed
attempts become successful.
I think you will be surprised at the uses for this report.
At the
very least, it offers another view of what is available
to a system
administrator on AIX.
lptran: A Transfer Command for the LP Spooler on AIX
A major shortcoming of IBM's version of the LP spooler
on AIX is the
lack of a command that lets you easily transfer a job
from one queue
to another. Many third-party spooler packages offer
this feature,
but that usually means using their spooler rather than
the LP spooler.
Other versions of UNIX do provide transfer commands:
on SCO UNIX,
for example, lpmove moves a print job from one queue
to another. This
command can move either a single print job to another
queue or all
print jobs from one queue to another.
I developed the lptran command (Listing 2) to provide
the transfer
functionality that the normal AIX LP spooler lacks.
The command can
copy a printout from one queue to another queue, but
cannot transfer
all of the print jobs from one queue to another, as
lpmove
does. This feature would be simple to add but is not
part of this
program. The lptran command also does not delete the
old print
job; again, this would be a simple modification.
Explanation of the AIX LP Spooler
In AIX 3.2 the LP spooler header files are in the directory
/var/spool/lpd/qdir,
while in AIX 3.1 they are in the directory /usr/lpd/qdir.
The layout of the spooler header file is very cryptic.
Rather than
try to explain the entire layout, I focus here only
on the parts the
application needs.
The first line in the file holds the number of the print
job. The
middle of the file contains information about the state
of the user's
environment when the print job was queued. Also included
in this section
are the queue name, the title of the print job, the
name of the person
who submitted the job, and the host name of the system.
The last section
of this file contains the names of the actual files
to be printed
(these can be either copies of the files in the spool
directory or
the full path names of the actual files). Do not try
to manually edit
this file; if you do, the lp spooler will reject it.
Program Explanation
Since the program builds a linked list to hold the entries
from the
/var/spool/lpd/qdir directory, the first step is to
set up
a structure to hold these. I defined the structure t_type
to
hold the file name and the link to the next structure.
I set the length
of the name to 255 because this is MAX_PATH on AIX.
The first procedure, get_files(), opens the directory
using
the dirent functions and builds a linked list of the
entries.
It skips the first two entries (. and ..), then returns
a pointer
to the first member of the list.
Using the list built by get_files, the procedure find_job_number()
reads the first line from each of the files and checks
it against
the job number that the user entered. This procedure
return a NULL
pointer if the job number is not found; otherwise, it
returns a
pointer to the correct entry.
The procedure read_and_transfer() opens the header files
and
skips past the unused information. It then reads each
string from
the file, checking to see if it is a regular file and
if the path
name is less than MAX_PATH. It then adds that string
to the
transfer string. I allocated only 4096 bytes for the
transfer string.
In most cases this should be more than enough, but if
you need
more, simply increase this number.
The last procedure, is_file(), simply checks to see
if a file
is a regular file. It returns TRUE if the file is regular;
otherwise, it returns FALSE.
I could have skipped the building of the linked list
and simply opened
each file by combining get_files() and find_job_number(),
but I decided to leave this this structure in place
so that I could
easily implement the second part of the SCO lpmove command
at a later time.
Command Syntax
To compile for AIX 3.1:
cc -DAIX31 -olptran lptran.c
To compile for AIX 3.2:
cc -DAIX32 -olptran lptran.c
To use:
lptran <job_number> <queue>
Conclusion
If you are using the AIX LP spooler, I am sure you have
encountered
the need for this command. You've probably also wondered,
as I have,
why IBM has not implemented the command in some form.
I hope our version
will help you fill the hole in the AIX LP spooler.
About the Author
Jeff Courington has worked on various forms of UNIX
over the past 8 years, including
AIX, SCO, HP/UX, and SVR3 variants from Silicon Valley
Software and Versyss
Corporation. He presently has a network of 11 IBM RS/6000s
and various
HP/UX machines connected over the wide area with TCP/IP
through the use
of Cisco routers. Jeff graduated from Virginia Polytechnical
Institute
and State University with a BS in Computer Science.
He is currently working
on his MS in Computer Science at Virginia Commonwealth
University and can
be reached from the Internet at attmail.com!aix!jeff.
|