Two Handy AIX Tools: The Failed Login Report and lptran
AIX is a very distinctive implementation of UNIX, with
its own strengths
and weaknesses. In the course of administering an AIX
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
allows you to move print jobs from one queue to another
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
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
Remember that the failedlogin file can only track logins
correct login names and incorrect passwords. All other
assigned to the login UNKNOWN. I found that on my system
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
and /usr/adm/wtmp. The who command uses the /etc/utmp
file to show the current users on the system, while
file contains system accounting records for connections.
If the login
process fails, the file that gets updated is
The failedlogin file records the failed login attempts
order. The AIX manual, Elements Of AIX Security: R3.1
(Doc # GG42-3622-1),
warns that this file should not be edited. To recover
however, it can be deleted to allow the system to recreate
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
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_time, and ut_termio. The ut_exit structure
contains the process termination status and the exit
fields tell something about why and how the process
The ut_time structure records the login time of the
The ut_termio structure records the initial terminal
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
in the /etc/utmp file, which keeps the current user
AIX users are probably familiar with the bug in the
that shows ghost users on the system (a pseudo-terminal
it is logged in even though it really is not). By searching
the /etc/utmp file and only showing logins with the
equal to USER_PROCESS, you can get a real list of who
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
see whether the report should cover all users or a specific
The meat of the program is in the print_users procedure,
first opens the failedlogin file at line 65. It checks
against the string NOBODY on line 69 to see if the report
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
using the structure utmp each read is for a record the
of this structure. The while loop consists of various
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
this into a tm structure, which asctime then converts
to the format that we expect from the date command.
and 85 finish the loop and print the number of failed
86 prints a form feed, Octal 14, so that the printer
in alignment and return the number of users counted.
When I run the report, I usually use a small shell script
the printout by user:
lsuser -a ALL|cut -f1 -d" "|xargs \
-i% flogin -u %
Figure 4 shows sample output from the program.
The failed login report can be useful for system security.
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
the /usr/adm/wtmp file only contains successful logins,
accounting reports will not show failed attempts at
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.
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
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
functionality that the normal AIX LP spooler lacks.
The command can
copy a printout from one queue to another queue, but
all of the print jobs from one queue to another, as
does. This feature would be simple to add but is not
part of this
program. The lptran command also does not delete the
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
while in AIX 3.1 they are in the directory /usr/lpd/qdir.
The layout of the spooler header file is very cryptic.
try to explain the entire layout, I focus here only
on the parts the
The first line in the file holds the number of the print
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
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.
Since the program builds a linked list to hold the entries
/var/spool/lpd/qdir directory, the first step is to
a structure to hold these. I defined the structure t_type
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
the dirent functions and builds a linked list of the
It skips the first two entries (. and ..), then returns
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
the job number that the user entered. This procedure
return a NULL
pointer if the job number is not found; otherwise, it
pointer to the correct entry.
The procedure read_and_transfer() opens the header files
skips past the unused information. It then reads each
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
transfer string. I allocated only 4096 bytes for the
In most cases this should be more than enough, but if
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.
To compile for AIX 3.1:
cc -DAIX31 -olptran lptran.c
To compile for AIX 3.2:
cc -DAIX32 -olptran lptran.c
lptran <job_number> <queue>
If you are using the AIX LP spooler, I am sure you have
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
HP/UX machines connected over the wide area with TCP/IP
through the use
of Cisco routers. Jeff graduated from Virginia Polytechnical
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.