Exit Points for AS/400 Control
Language Commands
Part 2 --- Auditing
Command Usage in Real Time
By Dan Riehl
©2004-2009
Dan Riehl, All Rights
Reserved
Do you want to be alerted when someone tries to restore objects onto your system? Or maybe you want to know when someone starts up a TCP/IP server program, or changes a system value. In the past it was quite difficult to collect these events in real time, but with the capability to monitor for sensitive commands, this is now a trivial task.
In part one of this series the focus of the column was the exit points available for CL commands, and dealt quite specifically with the Change Command exit point. As noted in that article, there is another command exit point that may be used to monitor and audit commands as they are executing. This is the Command Analyzer Retrieve exit point.
This new capability allows you to capture commands as they execute and do something with the information collected. Unlike the Command Analyzer Change exit point discussed last month, the Retrieve exit point does not allow you to send information back to the command analyzer. This limits the capabilities of this exit point to be a logging and auditing exit point only.
The example program supplied in this article is called whenever someone executes the Restore Object(RSTOBJ) command. It retrieves the command information and records the RSTOBJ command string and other useful information in the system's QHST history log. You could certainly do other things with the command string data, but the purpose of this simple example is to illustrate the process of creating and registering an exit program.
The Command Analyzer
Retrieve exit point
Each IBM supplied exit point has an assigned name and an exit point interface. The exit point interface is a list of parameters the command analyzer exchanges with your exit program. The name of the exit point for the command analyzer retrieve command exit point is QIBM_QCA_RTV_COMMAND. This exit point occurs after the command analyzer has done much of its work, but before control is passed to the Command Processing Program(CPP).
Since the exit program is called before the CPP, the exit program cannot predict whether the command will complete normally or abnormally. It only knows that the command is being attempted, with no knowledge of, or potential impact on, the outcome of the command processing program(i.e. whether the operation will fail or succeed).
The name of the exit point interface for this exit point is named RTVC0100. This exit point interface is similar to the CHGC0100 interface discussed in last month's issue of iSeries. The exit program is not passed the RTVC0100 interface in separate parameters, but as one big lump of data. Your program needs to parse out the individual data elements of the RTVC0100 parameter which is illustrated in Figure 1.
Figure 1 The Retrieve Command Exit Point Interface
Parameter 1
|
Description |
Values |
Type and length |
Exit Point Name |
QIBM_QCA_RTV_COMMAND |
Char 20 |
|
Exit Point Interface Format Name |
RTVC0100 |
Char 8 |
|
Command Name |
Name of the command for which the exit program is registered |
Char 10 |
|
Command Library Name |
Name of the library where the Command resides |
Char 10 |
|
Reserved for future use |
|
Char 4 |
|
Offset to Original Command String |
The offset to the beginning of the original Command String |
Binary (4) |
|
Length of Original Command String |
The length of the original Command String |
Binary (4) |
|
Offset to Replacement Command String |
The offset to the beginning of the replacement Command String if the command was changed by the Change command exit point. Otherwise, the value is 0. |
Binary (4) |
|
Length of Replacement Command String |
The length of the replacement Command String if the command was changed by the Change command exit point. Otherwise, the value is 0. |
Binary (4) |
|
Original Command String |
The original Command String before any changes |
Char * (Variable Length) |
|
Replacement Command String |
The Command String that you want to run in place of the original command |
Char * (Variable Length) |
As with all registered exit points, you can add your own exit point program using the ADDEXITPGM(Add Exit program) command. In the case of the Retrieve Command exit point, you need to specify the name of the command, and the library in which the command resides in the PGMDTA parameter as in the following example. For the Retrieve command exit point, you can register up to 10 programs per command, incrementing the PGMNBR parameter for each consecutive program. This allows you to run a sequence of programs, or allows you to run a third party, or vendor supplied, exit program, and still run your own program.
ADDEXITPGM EXITPNT(QIBM_QCA_RTV_COMMAND) +
FORMAT(RTVC0100) +
PGMNBR(1) +
PGM(MYLIB/RSTOBJEXIT) +
TEXT('Exit
program for RSTOBJ') +
PGMDTA(*JOB
20 'RSTOBJ QSYS')
The PGMDTA parameter must be specified with a data length of 20. You must specify the command name in the first 10 positions, and the command library in the next 10 positions, as in the example. The command analyzer is directed to use the exit program RSTOBJEXIT in library MYLIB whenever a request is made to run the RSTOBJ command found in the QSYS library.
There are certain commands for which exit point programs may not be defined. These include CL compiler directing statements, commands found in libraries QSYS38 and QUSER38, and a few others. Following is the list of commands for which exit programs may not be registered.
CALLPRC |
CHGVAR |
CNLRCV |
COPYRIGHT |
DCL |
DCLF |
DO |
ENDDO |
ENDPGM |
ENDRCV |
GOTO |
IF |
MONMSG |
PGM |
RCVF |
RETURN |
SNDF |
SNDRCVF |
TFRCTL |
WAIT |
CALL |
RTVxxxxxx |
|
|
Figure 2 contains a sample exit program that may be used for the RSTOBJ command. The exit program sends a message to a message queue each time the RSTOBJ command is used. It also sends a message to the QHST history log. The processing performed in this program is quite simple, but it does provide a template that you can use to create your own program.
You should note that this exit program is registered to only monitor for the usage of the RSTOBJ command. However, you could use the same program to monitor for all RSTxxx commands by adding the same exit point program(ADDEXITPGM) for each RSTxxx command(e.g. RSTLIB, RST, RSTLICPGM, etc).
Figure 2 Command Exit Point
Program Example
========================================================================
/* Program Name: RSTOBJEXIT
*/
/* Purpose: This is the exit program for
the Command RSTOBJ. */
/*
Exit Point IS QIBM_QCA_RTV_COMMAND
*/
/*
Parameter format is RTVC0100.
*/
/* - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - */
/* Copyright© 2002 Dan Riehl, The 400 School, Inc.
*/
PGM PARM(&ExitInfo)
DCL &Exitinfo *Char 2000 /* RTVC0100 Interface Data */
DCL &User *Char 10
DCL &JobName *Char 10
DCL &OffsetDec *Dec (7 0)
DCL &CmdLenDec *Dec (7 0)
/*
Exit point interface RTVC0100 for QIBM_CA_RTV_COMMAND exit point */
DCL &ExitPoint *CHAR 20 /* Exit Point name
*/
DCL &ExitFormat *CHAR 8 /* Exit Point Format
*/
A
DCL &CmdLib *CHAR 10 /* Command Library
*/
DCL &OffsetO *CHAR 4 /* Offset to command string
*/
DCL &CmdLengthO *CHAR 4 /* Command string length
*/
DCL &OffsetR *CHAR 4 /* Offset to command string */
DCL &CmdLengthR
*CHAR 4 /* Command string length
*/
DCL &CmdString *CHAR 2000 /* Command String
*/
/*
Error handling variables
*/
DCL &MsgID *CHAR 7
DCL &MsgFile *CHAR 10
DCL &MsgFLib *CHAR 10
DCL &MsgData *CHAR 512
MONMSG CPF0000 EXEC(GOTO ERROR)
/*
Parse out the exit info data
*/
CHGVAR
&ExitPoint %SST(&ExitInfo
1 20)
CHGVAR
&ExitFormat %SST(&ExitInfo
21
8)
CHGVAR
&CmdName %SST(&ExitInfo
29 10)
CHGVAR
&CmdLib %SST(&ExitInfo
39 10)
B
CHGVAR
&CmdLengthO %SST(&ExitInfo
57 4)
CHGVAR
&OffsetR %SST(&ExitInfo
61 4)
CHGVAR
&CmdLengthR %SST(&ExitInfo
65 4)
/*
Check to see if command was replaced by Change Command Exit */
IF (%BIN(&OffsetR) = 0) DO
/* Command not replaced */
CHGVAR
&CmdLenDec %BIN(&CmdlengthO)
C
ENDDO
CHGVAR
&CmdLenDec %BIN(&CmdlengthR)
CHGVAR
&OffsetDec (%BIN(&OffsetR) + 1) /* Set offset */
ENDDO
CHGVAR &CmdString
%SST(&ExitInfo &OffsetDec &CmdLenDec)
RTVJOBA JOB(&JobName)
USER(&User)
SNDPGMMSG
MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Restore +
D
*TCAT '. The command executed is:' *BCAT +
&CmdString) TOMSGQ(RESTORE QHST)
ENDIT:
RETURN /*
/*
Error handling */
ERROR:
RCVMSG MSGTYPE(*LAST) MSGDTA(&MsgData)
+
MSGID(&MsgID)
MSGF(&MsgFile) +
SNDMSGFLIB(&MsgFLib)
MONMSG
CPF0000 EXEC(RETURN)
SNDPGMMSG
MSGID(&MsgID)
MSGF(&MSGFLIB/&MsgFile) +
MSGDTA(&MsgData)
MSGTYPE(*ESCAPE)
MONMSG
CPF0000 EXEC(RETURN)
ENDPGM
Examining the RSTOBJ
command Exit Program
The exit program receives only one parameter. As mentioned, the parameter contains the RTVC0100 data structure that must be parsed into its individual fields. At A in Figure 2, the fields are defined that will be used to store the RTVC0100 format data once it is parsed. At B , the RTVC0100 format is parsed into it's component parts.
At C , a determination is made as to whether the original command was replaced by a Command Analyzer Change Exit program. If it was replaced, then the command string that is being executed is found at the offset stored in the variable &OFFSETR, otherwise the offset to the command is found in the variable &OFFSETO. As you can see, the determination is made by checking the replacement offset(&OFFSETR) for a value of 0(zero). If the replacement offset is 0, the command was not replaced by a Change Command Exit program.
At D in Figure 2, the User and Job name are retrieved from the job running the RSTOBJ command. This information is collected so that it can be included in the informational message that is sent, also at D . The message is sent to two message queues; RESTORE and QHST. You can replace these in the code to suit your individual requirements.
Figure 3 shows the resulting Display Messages screen when after a few RSTOBJ commands are executed. The same information is written to the QHST history log to assist in your auditing for the use of the RSTOBJ command.
Don't forget to Exit
OS/400 has added numerous exit points over the last several releases. As you become familiar with command exit points and the customized processing you can perform, you may want to delve further into more of the exit points. There are exit points for all kinds of things, like Save and Restore functions, User Profile maintenance, and network access control. The toolbox is booming! You can use exit point programs to make your system administration tasks a lot easier than they might have been in the past…… So don't forget to Exit!
Figure 3… The
resulting Display Messages screen
Display
Messages
System: MYAS400
Queue . . . . . : RESTORE Program . . . . : *DSPMSG
Library . . . : QUSRSYS Library . . . :
Severity
. . . : 00 Delivery . . . :
*BREAK
Type reply (if required), press Enter.
Restore operation in progress from user TESTUSER from job QPADEV0013.
The
command executed is: RSTOBJ OBJ(QXXXXX)
SAVLIB(MYLIB) DEV(*SAVF)
SAVF(MYSAVF).
Restore operation in progress from user ANYUSER from job QPADEV0015. The
command executed is: RSTOBJ OBJ(QCLSRC)
SAVLIB(YOURLIB) DEV(*SAVF)
SAVF(ANYSAVF).
Restore operation in progress from user QSYSOPR from job QPADEV0010.
The
command executed is: RSTOBJ OBJ(MYPROGRAM)
SAVLIB(QGPL) DEV(*SAVF)
SAVF(OPERSAVE).
Bottom
F3=Exit F11=Remove a message F12=Cancel
F13=Remove all F16=Remove all except unanswered F24=More keys
©2004-2009 Dan Riehl
All Rights Reserved