User Specified Program Limitation Feature

IBM® Connect:Direct® can call User Specified Programs (USPs) as Exits and Run Tasks - each of which can have any load module name, except Stage 1 Security and Stage 1 Submit Exits. Also, the STAGE2 Security exit’s internal call to the PROCEXIT load module can have any name.

The USP Name Limitation Feature allows the installation to limit the name of any USP to provide a more secure name space for these programs, and so help prevent accidental or deliberate unpermitted calls to programs in APF authorized concatenations. Note that APF already prevents, by ABEND, IBM Connect:Direct from doing any MVS LINK, LOAD, ATTACH, etc. to a program from an unauthorized concatenation.

DGAXTABL

The control point of the feature is DGAXTABL, which is distributed both as a load module in SDGALOAD and as a sample source member in SDGASAMP. As distributed, DGAXTABL allows exit calls to use names that start with DGAX (specified as ‘DGAX*’) along with a few other common program name prefixes. Thus, it is very important that DGAXTABL be customized and installed correctly in the IBM Connect:Direct load library concatenation before IBM Connect:Direct is started. DGAXTABL is not dynamically refreshable, and so IBM Connect:Direct must be recycled to bring in any changes to it. However, given the flexibility of the wildcard characters allowed, very few modifications will be needed when implemented in conjunction with strict USP naming conventions. Sample JCL is provided in SDGAJCL member DGAJTABL to assemble and link DGAXTABL.

Note: To update DGAXTABL via SMP/E USERMOD, refer to SDGASAMP member DGAUTAB. Add your modifications to DGAUTAB as IEBUPDTE changes, then RECEIVE and APPLY the USERMOD. Ensure you take backups of DGAXTABL from both SDGASAMP and SDGALINK. Optionally, this USERMOD will assemble and link the DGAXTABL module, eliminating the need for a separate job.

Feature Disablement

Note: WARN mode is recommended for initial implementation of DGAXTABL to help identify all exit and Run Task program names without failing those programs or startup. Once the names are known, add them to the appropriate section in DGAXTABL and reassemble before turning on protection.

The feature can be disabled, either partially or completely. USPs can be validated by exact program name, or a program name mask with wildcards (*=multi char; %=single char). For example, specifying a name of a single asterisk (*) in any of the DGAXTABL lists allows any USP to be used for that Type of exit, or Run Task. Enforcement can be postponed by using WARN mode, with or without the WARN WTO option. WARN mode allows legacy operation to continue, while flagging the names of those USPs that would not be allowed were enforcement turned ON. Finally, the entire feature can be completely disabled, making the product behave in legacy mode, except that load module DGAXTABL must be present and pass all verification checks. Note that simply deleting or renaming the DGAXTABL load module will not disable the feature, but rather will prevent IBM Connect:Direct from initializing. With the feature completely disabled, there is no enforcement, and all exits are allowed. Otherwise, all exits are validated. The feature is completely disabled by specifying DGAXTABL HEADENFO OFF. It is put in WARN mode by specifying DGAXTABL HEADENFO WARN.

Categories and Types of USP Calls

DGAXTABL can have 0 or more names in the list for each Type of USP. Some Types are categorized as static, meaning they are specified in the INITPARMs and are validated when Connect:Direct is initialized, and never changes for the life of theIBM Connect:Direct instance (not even by an INITPARM REFRESH). If any static USP fails validation, and enforcement is turned ON, IBM Connect:Direct initialization terminates with CC=16. If enforcement is turned OFF or is in WARN mode, Connect:Direct initialization proceeds, and all static exits are allowed.

The rest of the exits are categorized as dynamic – they are specified in a Process (RUNTASK, IOEXIT or DATAEXIT) or inside the Stage 2 Security exit code when PROCEXIT=YES is used. Validation for a dynamic exit occurs just before it is called. If a dynamic exit USP fails validation, and enforcement is turned ON, the exit is not called, and the Process is terminated with RC=8. If enforcement is turned OFF or is in WARN mode, the call is allowed, and processing continues normally, but with a warning message and possibly a WTO.

The following table contains the Types of USP calls, their Categories, and how they are specified or sourced from:
Table 1.
USP Type USP Category USP specified by
ALLOEXIT Static INITPARM ALLOCATION.EXIT
RUNJEXIT Static INITPARM RUN.JOB.EXIT
RUNTEXIT Static INITPARM RUN.TASK.EXIT
SECUEXIT Static INITPARM SECURITY.EXIT
PROCEXIT Dynamic SDGASAMP DGAMGSAF DGASECUR
STATEXIT Static INITPARM STATISTICS.EXIT
SUBMEXIT Static INITPARM SUBMIT.EXIT
TMNTEXIT Static INITPARM TAPEMOUNT.EXIT
DATAEXIT Dynamic Process COPY DATAEXIT
IOEXIT Dynamic Process COPY IOEXIT
RUNTASK Dynamic Process RUN TASK

Initialization Messages

At IBM Connect:Direct initialization, the DGAXTABL header is verified. First all the values are listed in DDNAME NDMLOG. Then any errors are listed, and the entire line is issued as a SITA490I WTO. The following example shows the NDMLOG header verification messages including all the errors that can be in the header.
DGADTABL ENTERED, PARM1='++VERIFY' PARM2='DGAXTABL' PARM3='DMINIT2 '
DGADTABL Verify Exit Name Security Table='DGAXTABL'
DGADTABL DGAXTABL HEADEYE ='OGAXTABL'
DGADTABL DGAXTABL HEADTLEN= 00000000
DGADTABL DGAXTABL HEADHLEN= 00000000
DGADTABL DGAXTABL HEADPTF ='R000000 '
DGADTABL DGAXTABL HEADDATE='20230208'
DGADTABL DGAXTABL HEADTIME='18.14   '
DGADTABL DGAXTABL HEADENFO='NO  '
DGADTABL DGAXTABL HEADWWTO='NO  '
DGADTABL DGAXTABL HEADWDDN=' ECURITY'
DGADTABL DGAXTABL HEADENTA= 194B50B0
DGADTABL DGAXTABL HEADENTL= 00000000
DGADTABL DGAXTABL HEADENT#= 00000000
DGADTABL DGAXTABL HEADENTE= 194B5160
DGADTABL DGAXTABL HEADUNUS= 00000000 00000000 00000000 00000001
DGADTABL DGAXTABL HEADDESC='Correct:Direct z/OS Exit Security Table.'
DGADTABL DGAXTABL HEADEYE  'OGAXTABL' is invalid. It must be 'DGAXTABL'.
DGADTABL DGAXTABL HEADHLEN  00000000  is invalid. It must be 00000080 .
DGADTABL DGAXTABL HEADENFO 'NO  '     is invalid. It must be 'ON  ', 'OFF ', or 'WARN'.
DGADTABL DGAXTABL HEADWWTO 'NO  '     is invalid. It must be 'ON  ' or 'OFF '.
DGADTABL DGAXTABL HEADWDDN ' ECURITY' is invalid. It must be a valid DDNAME.
DGADTABL DGAXTABL HEADENTL  00000000  is invalid. It must be 00000010 .
DGADTABL DGAXTABL HEADENT#  00000000  is invalid. It must be 0000000C .
DGADTABL DGAXTABL HEADUNUS (above)    is invalid. It must be all hex zeroes.
DGADTABL DGAXTABL HEADDESC (above)    is invalid. It must be 'Connect:Direct z/OS Exit Security Table.'.
DGADTABL EXITING, RC=12.
After that, if there are no errors in the header, the body of DGAXTABL is listed and verified. The following example shows the body verification messages including all the errors that can be in it. Any errors have a brief description after the COUNT, and the entire line is issued as a SITA490I WTO.
DGADTABL DGAXTABL ENTRYTBL TYPE='ALTTEXIT' A(LIST)=194B5148 LIST='ALLOEXIT' COUNT=00000001  Invalid TYPE
DGADTABL DGAXTABL ENTRYTBL TYPE='DATAEXIT' A(LIST)=00000000 LIST='........' COUNT=00000001  Invalid LIST
DGADTABL DGAXTABL ENTRYTBL TYPE='IOEXIT  ' A(LIST)=194B5168 LIST='IOEXIT  ' COUNT=00000000
DGADTABL DGAXTABL ENTRYTBL TYPE='PROCEXIT' A(LIST)=194B5178 LIST='PROCEXIT' COUNT=00000001
DGADTABL DGAXTABL PROGRAM  LIST='PROCEXIT' A(PROG)=194B5180 PROG='DGAX*   ' PROG#=00000001
DGADTABL DGAXTABL ENTRYTBL TYPE='RUNJEXIT' A(LIST)=194B5188 LIST='RUNJEXIT' COUNT=00000001
DGADTABL DGAXTABL PROGRAM  LIST='RUNJEXIT' A(PROG)=194B5190 PROG='DGAX*   ' PROG#=00000001
DGADTABL DGAXTABL ENTRYTBL TYPE='RUNTASK ' A(LIST)=194B5198 LIST='RUNTASK ' COUNT=00000005
DGADTABL DGAXTABL PROGRAM  LIST='RUNTASK ' A(PROG)=194B51A0 PROG='DGAX*   ' PROG#=00000001
DGADTABL DGAXTABL PROGRAM  LIST='RUNTASK ' A(PROG)=194B51A8 PROG='DMRT*   ' PROG#=00000002
DGADTABL DGAXTABL PROGRAM  LIST='RUNTASK ' A(PROG)=194B51B0 PROG='2MRT*   ' PROG#=00000003  PROG Char 1
DGADTABL DGAXTABL PROGRAM  LIST='RUNTASK ' A(PROG)=194B51B8 PROG='D RT*   ' PROG#=00000004  PROG Char 2
DGADTABL DGAXTABL PROGRAM  LIST='RUNTASK ' A(PROG)=194B51C0 PROG='DMRT012^' PROG#=00000005  PROG Char 8
DGADTABL DGAXTABL ENTRYTBL TYPE='RUNTEXIT' A(LIST)=194B51C8 LIST='RUNTEXIT' COUNT=00000001
DGADTABL DGAXTABL PROGRAM  LIST='RUNTEXIT' A(PROG)=194B51D0 PROG='DGAX*   ' PROG#=00000001
DGADTABL DGAXTABL ENTRYTBL TYPE='SECUEXIT' A(LIST)=194B51D8 LIST='SECUEXIT' COUNT=00000003
DGADTABL DGAXTABL PROGRAM  LIST='SECUEXIT' A(PROG)=194B51E0 PROG='DMGSAF  ' PROG#=00000001
DGADTABL DGAXTABL PROGRAM  LIST='SECUEXIT' A(PROG)=194B51E8 PROG='DGAMGSAF' PROG#=00000002
DGADTABL DGAXTABL PROGRAM  LIST='SECUEXIT' A(PROG)=194B51F0 PROG='DGAX*   ' PROG#=00000003
DGADTABL DGAXTABL ENTRYTBL TYPE='STATEXIT' A(LIST)=194B51F8 LIST='STATEXIT' COUNT=00000001
DGADTABL DGAXTABL PROGRAM  LIST='STATEXIT' A(PROG)=194B5200 PROG='DGAX*   ' PROG#=00000001
DGADTABL DGAXTABL ENTRYTBL TYPE='SUBMEXIT' A(LIST)=194B5208 LIST='SUBMEXIT' COUNT=00000001
DGADTABL DGAXTABL PROGRAM  LIST='SUBMEXIT' A(PROG)=194B5210 PROG='DGAX*   ' PROG#=00000001
DGADTABL DGAXTABL ENTRYTBL TYPE='TMNTEXIT' A(LIST)=194B5218 LIST='TMNTEXIT' COUNT=0001869F  Excess COUNT
DGADTABL DGAXTABL Maximum allowed number of programs in a list=0000270F
 Valid TYPEs and LISTs:
  DATAEXIT IOEXIT   PROCEXIT RUNJEXIT RUNTASK  RUNTEXIT SECUEXIT STATEXIT SUBMEXIT TMNTEXIT
DGADTABL EXITING, RC=12.
After that, if there are no errors in DGAXTABL, any static exits specified in the INITPARMs are validated. For each exit specified, if the USP is not matched with any name in the LIST for that TYPE, Connect:Direct issues an error message, both to DDNAME in DGAXTABL HEADWDDN (the distributed value is SECURITY) and as a SITA490I WTO
$0000 10:39:51.54  DGADTABL DGAXTABL  LIST='ALLOEXIT' does not allow 'IGGPRE00'. RC=8.

SITA490I DGADTABL DGAXTABL  LIST='ALLOEXIT' does not allow 'IGGPRE00'. RC=8.
The validation routine sets a RC of 4 or 8, depending on DGAXTABL HEADENFO. If RC > 4, IBM Connect:Direct issues a SITA499E termination message to NDMLOG and as a WTO:
SITA499E DGADTABL RC= 8. CD Initialization Terminated.
*SITA499E DGADTABL RC= 8. CD Initialization Terminated. See NDMLOG DD.

After IBM Connect:Direct initialization successfully completes, the static exits are called without checking DGAXTABL.

Post-Initialization

After initialization, the static exits are not validated further, having been validated once and are not refreshable. The dynamic exits, for which the USP names are not knowable until Process execution, are validated immediately before they are called. If a dynamic exit does not pass validation, DGAXTABL HEADENFO determines whether the exit is allowed or not. When DGAXTABL HEADENFO is ON, a dynamic exit validation error prevents the exit from being called and terminates the step. It does not cause Connect:Direct to terminate. When DGAXTABL HEADENFO is WARN, the exit call is allowed.

HEADENFO ON

When a dynamic exit fails validation, and HEADENFO is ON, error messages are written to the DDNAME specified by the DGAXTABL HEADWDDN, just like for static exits. If DEBUG flag ‘00100000’ is ON, then all exit validation messages, not just error messages, will be written to HEADWDDN. If DEBUG flag ‘80000000’ is ON and TAID=P or S, then all exit validation messages will be written to the fixed Process trace DDNAME RADBDD01. If the DEBUG flag ‘04000000’ is also on, they will be written to the Task Trace DDNAME (Rnnnnnnn) instead of RADBDD01.

Dynamic exit validation error messages are also issued as SITA490I WTOs.
SITA490I DGADTABL DGAXTABL  LIST='RUNTASK ' does not allow 'IGGPRE00'.
Then, a SITA49nE WTO is issued indicating the dynamic exit was not allowed. The value of n indicates the TYPE of dynamic exit, where 1=RUNTASK, 2=IOEXIT, 3=DATAEXIT, and 5=PROCEXIT.
*SITA491E DGADTABL RC= 8. RUNTASK IGGPRE00 not allowed.
The SITA49nE MSGID is put into the SVTM052I message along with the RC of 8 for the Process Step.
SVTM052I IGGPRES1 RUN TASK TESTRUNT(       1) PNODE=CD.ART
SVTM052I      #### COMPLETED  00000008/SITA491E

HEADENFO WARN

When DGAXTABL HEADENFO is WARN, no error WTOs (SITA49nE) are issued. A warning WTO (SITA490I) will be issued if HEADWWTO is ON. Step end message SVTM052I is not affected by the warning. Warning messages and WTOs are only seen on the side they occur on, in contrast to error MSGIDS which are also seen in the SVTM052I message on the other side.

Miscellaneous

It is highly recommended that you use the distributed value of ‘SECURITY’ for DGAXTABL HEADWDDN. If you use other DDNAMEs, the results may be unpredictable. If you don’t use the distributed value, please verify the DDNAME you choose has the expected messages before implementing it into production.

It is also recommended that you not change any other fields in DGAXTABL header except HEADENFO and HEADWWTO. If you do, the changes may not pass verification.

It is also recommended that you not change any fields in DGAXTABL ENTRYTBL section. If you do, the changes may not pass verification.

It is also recommended that you not delete or add any list sections (all list sections are below the ENTRYTBL section). Each list section must start with the same 8 character type as the ENTRYTBL entry for it. You can delete all names from a list, but not the type at the top. You can add any number of names to a list, in any order, each of which can contain wild cards (‘*’ is a 0-8 char wildcard and ‘%’ is a single character wildcard). You must preserve the assembler instructions (like EQU) that tell the assembler how large the various lists and entries are.