This chapter explains how to write exit programs.
A user exit is a point in MSS itself at which control can be transferred to a user-written program and at which MSS can resume control after it has finished. The following types of user exit program are supported:
You must write separate global and task-related user exits. You must write all user exit programs in non-mainframe COBOL. They must not use EXEC CICS commands, and they must use native addressing for pointers.
You must enable each user exit that an application program needs before it is called, and you can disable it when the application program has finished with it, though you do not have to; user exits are always disabled by default when CICS starts up. You use the CICS command ENABLE PROGRAM to enable a user exit program, and the CICS command DISABLE PROGRAM to disable a user exit program. If you try to enable an invalid exit an EIBRCODE of X'804000' is returned. If you try to enable an exit that is valid but not implemented, an EIBRCODE of X'804010' is returned. The EXTRACT EXIT command is also provided; you use this to gain access to the work area of a user exit program. For details of the level of support provided for these commands see the topic System Programmers Commands.
You must define each user exit program as a program (in the PLT) and the definition must be available on the running system.
For information about global user exits and task-related user exits see the IBM manual CICS/ESA 3.3 Customization Guide. This manual contains a list of valid user exit points.
You need to include the following two copybooks in your user exit program, whether it is for a global user exit or a task-related user exit:
78 78-uxi-TRUE value 1.
78 78-uxi-XZCATT value 2.
78 78-uxi-XZCIN value 3.
78 78-uxi-XZCOUT value 4.
78 78-uxi-XEIIN value 5.
78 78-uxi-XEIOUT value 6.
***--------------------------------------------------------------*
*** Base parameters *
***--------------------------------------------------------------*
01 uxi-user-exit-interface.
02 uxi-operational-flags-ptr pointer.
02 uxi-scheduling-flags-ptr pointer.
02 uxi-global-area-ptr pointer.
02 uxi-global-area-length pic x(4) comp-5.
02 uxi-local-area-ptr pointer.
02 uxi-local-area-length pic x(4) comp-5.
02 uxi-dfheiblk-ptr pointer.
02 uxi-unit-of-recovery-ptr pointer.
***--------------------------------------------------------------*
*** Exit specific parameters *
***--------------------------------------------------------------*
02 uxi-exit-specific-ptrs. *> XZCATT In/Out XEin/out
03 uxi-resource-ptr pointer. *> TCTTE TCTTE Arg list
03 uxi-resource-data-ptr pointer. *> TIOA TIOA user-id
03 uxi-res-data-len-ptr pointer. *> * *
03 uxi-aux-1-ptr pointer. *> APPC program
03 uxi-aux-1-length-ptr pointer. *> *
03 uxi-aux-2-ptr pointer. *> Tran Sys EIB
03 uxi-aux-2-length-ptr pointer. *>
03 uxi-aux-3-ptr pointer. *> TEUA TEUA
03 uxi-aux-3-length-ptr pointer. *> * *
03 uxi-aux-4-ptr pointer. *> ComA ComA
03 uxi-aux-4-length-ptr pointer. *> * *
03 pointer. *>
***--------------------------------------------------------------*
*** System parameters *
***--------------------------------------------------------------*
02 uxi-PCA-ptr pointer.
02 uxi-CSA-ptr pointer.
02 uxi-DCA-ptr pointer.
02 uxi-local-trace-table-ptr pointer.
01 lk-uxc-operation.
03 lk-uxc-exit-id pic x comp-x.
88 lk-uxc-TRUE-88 value 78-uxi-TRUE.
88 lk-uxc-XZCATT-88 value 78-uxi-XZCATT.
88 lk-uxc-XZCIN-88 value 78-uxi-XZCIN.
88 lk-uxc-XZCOUT-88 value 78-uxi-XZCOUT.
88 lk-uxc-XEIIN-88 value 78-uxi-XEIIN.
88 lk-uxc-XEIOUT-88 value 78-uxi-XEIOUT.
03 lk-uxc-schedule pic x.
88 lk-uxc-generic-88 value x'80'.
88 lk-uxc-TRUE-on-start-88 value x'80'.
88 lk-uxc-TRUE-on-sync-88 value x'40'.
88 lk-uxc-TRUE-on-prep-88 value x'20'.
88 lk-uxc-TRUE-on-tr-wrap-88 value x'01'.
03 lk-uxc-modifier pic x comp-x.
88 lk-uxc-user-syncpoint-88 value 0.
88 lk-uxc-task-syncpoint-88 value 1.
88 lk-uxc-task-start-88 value 2.
88 lk-uxc-initialization-88 value 254.
88 lk-uxc-shutdown-88 value 255.
03 lk-uxc-action pic x comp-x.
88 lk-uxc-syncpoint-commit-88 value 0.
88 lk-uxc-syncpoint-rollback-88 value 1.
88 lk-uxc-syncpoint-prepare-88 value 2.
03 lk-uxc-return-code pic x(4) comp-5.
01 lk-uxc-schedule-parm.
03 lk-uxc-schedule-byte pic x.
78 78-lk-uxc-TRUE-on-start value x'80'.
78 78-lk-uxc-TRUE-on-sync value x'40'.
78 78-lk-uxc-TRUE-on-prep value x'20'.
78 78-lk-uxc-TRUE-on-tr-wrap value x'01'.
Notes:
Here is a skeleton example of a task-related user exit program:
id division.
program-id. samptrue.
environment division.
configuration section.
input-output section.
data division.
file section.
working-storage section.
01 work-scl.
02 ws-allocate-local.
03 ws-allocate-local-ptr-x.
04 ws-allocate-local-ptr pointer.
03 ws-allocate-local-size pic x(4) comp-5.
03 ws-allocate-local-return pic x(4) comp-5.
88 ws-allocate-local-ok-88 value 0.
88 ws-allocate-local-no-space-88 value 1.
88 ws-deallocate-local-invalid-88 value 2.
88 ws-deallocate-inv-length-88 value 157.
02 ws-allocate-local-type pic x.
02 pic x.
02 ws-mfpm-register-flag pic x(2).
88 ws-mfpm-assign-24-88 value x'0000'.
88 ws-mfpm-absolute-24-88 value x'0200'.
88 ws-mfpm-assign-31-88 value x'0001'.
88 ws-mfpm-absolute-31-88 value x'0201'.
02 ws-mfpm-allocate-size pic x(4) comp-x.
02 ws-mfpm-allocate-ptr-x.
03 ws-mfpm-allocate-ptr pointer value null.
linkage section .
copy 'dfhcbuxi.cpy'.
copy 'dfhcbuxc.cpy'.
01 lk-global-area.
03 lk-ga-byte pic x occurs 0 to 4096
depending on uxi-global-area-length.
01 lk-local-area.
03 lk-la-byte pic x occurs 0 to 4096
depending on uxi-local-area-length.
procedure division using
uxi-user-exit-interface.
module-entry-point.
move 0 to return-code
set address of lk-uxc-operation
to uxi-operational-flags-ptr
set address of lk-uxc-schedule-parm
to uxi-scheduling-flags-ptr
move 0 to lk-uxc-return-code
*> -- Are we being called by an application?
*> -- (User application sets unused value in lk-uxc-schedule.)
if lk-uxc-schedule = x'02'
perform called-by-application
goback
end-if
*> -- Register syncpoint interest
move 78-lk-uxc-TRUE-on-sync to lk-uxc-schedule-byte
*> -- Register start of task interest
call "CBL_OR" using
78-lk-uxc-TRUE-on-start
lk-uxc-schedule-byte
by value 1
end-call
*> -- Register any other interest here by OR'ing bits
*> -- in lk-uxc-schedule-byte as above.
if lk-uxc-exit-id not = 0 *> -- handle only TRUEs
goback
end-if
evaluate true
when lk-uxc-initialization-88
when lk-uxc-shutdown-88
goback
when lk-uxc-task-start-88
perform save-TA-address
when lk-uxc-task-syncpoint-88
perform end-task-process
when lk-uxc-user-syncpoint-88
set address of lk-global-area
to uxi-global-area-ptr
set address of lk-local-area
to uxi-local-area-ptr
evaluate true
when lk-uxc-syncpoint-prepare-88
*> -- We haven't registered an interest for this
continue
when lk-uxc-syncpoint-commit-88
perform commit-process
when lk-uxc-syncpoint-rollback-88
perform rollback-process
end-evaluate
end-evaluate
goback
.
called-by-application section.
*> -- Add any code here that you wish to execute when
*> -- called by an application program.
*> -- This sample passes back the address of the local
*> -- task area.
set uxi-local-area-ptr to ws-mfpm-allocate-ptr
exit
.
save-TA-address section.
*> -- Convert local task area address and save in W/S.
exit
.
end-task-process section.
*> -- Insert code here that you wish to perform at
*> -- end of task.
exit
.
commit-process section.
*> -- Insert code here that you wish to perform at
*> -- user syncpoint.
exit
.
rollback-process section.
*> -- Insert code here that you wish to perform at
*> -- user backout.
exit
.
MSS emulates the behavior of the QUERY SECURITY CICS command by calling a user exit program. On the mainframe the QUERY SECURITY command interrogates an external security manager (ESM) such as IBM's RACF and returns information to the application about the level of access that a particular end-user is allowed to have to a particular resource. The user exit program must return the same information.
A default user exit program is supplied, and as supplied, this program returns NOT for all types of access. In other words, if your CICS application issues the QUERY SECURITY command, the result is always that access is denied. If you want any other behavior, you must alter the supplied exit program.
For details of the level of support provided see the topic QUERY SECURITY.
The user exit program must be called dfhuesm. A sample program dfhuesm.cbl, and a copy book defining the parameters passed between MSS and the exit program dfhuesm.cpy, are provided in the folder install-folder\base\source .
When the QUERY SECURITY command is issued, the input parameters are set using the information supplied by your application. The parameters are as follows:
| Field | Value |
|---|---|
| esm-version-no | Indicates the version of the parameter blocks. Micro Focus will increment this value if it issues an updated interface. |
| esm-user-id | The ID for the current user. If the user has not signed on, this field contains binary zeroes. |
| esm-opid | The operator ID associated with the user as defined in the sign-on table. If the user has not signed on, this field contains binary zeroes. |
| esm-opclass | The operator class associated with the user. This field contains character zeroes, unless the user has not signed on, in which case it contains binary zeroes. |
| esm-arg-01-flag | Unused. |
| esm-arg-02-flag | A value of 1 indicates that the application has used the RESTYPE keyword; the field esm-restype contains a valid resource type. |
| esm-arg-03-flag | A value of 1 indicates that the application has used the RESID keyword. This is mandatory, so this field is always set to 1. See the field esm-resid. |
| esm-arg-04-flag | A value of 1 indicates that the application has used the RESIDLENGTH keyword. See the field esm-residlength. |
| esm-arg-05-flag | A value of 1 indicates that the application has used the READ keyword. See the field esm-read. |
| esm-arg-06-flag | A value of 1 indicates that the application has used the UPDATE keyword. See the field esm-update. |
| esm-arg-07-flag | A value of 1 indicates that the application has used the RESCLASS keyword; the field esm-resclass contains a resource class. |
| esm-arg-08-flag | A value of 1 indicates that the application has used the ALTER keyword. See the field esm-alter. |
| esm-arg-09-flag | A value of 1 indicates that the application has used the CONTROL keyword. See the field esm-control. |
| esm-arg-10-flag | A value of 1 indicates that the application has used the LOGMESSAGE or the LOG keyword. See the field esm-logmessage. |
| esm-arg-11-flag | Unused. |
| esm-arg-12-flag | Unused. |
| esm-arg-13-flag | Unused. |
| esm-arg-14-flag | Unused. |
| esm-arg-15-flag | Unused. |
| esm-arg-16-flag | Unused. |
| esm-restype | If specified, this field contains one
of the following values:
|
| esm-resclass | If specified, this field contains the name of a resource class. |
| esm-residlength | If specified, this field contains the number of significant characters in the field esm-resid. |
| esm-resid | This field contains the ID of a resource, the user's access to which the application needs to query. It may either be a CICS resource ID of up to 12 characters or a user-defined resource ID of up to 240 characters. |
| esm-logmessage | If specified, this field notifies the user exit program as to whether security violations are to be logged or not. On the mainframe, this field is used to tell CICS to log security violations. It is provided for compatibility with the mainframe; however, security violations are not logged. |
The user exit program sets the output parameters, which are as follows:
| Field | Value |
|---|---|
| esm-eibresp | This field contains either zero to indicate that the QUERY SECURITY call is valid, or a non-zero value to indicate otherwise. This value is returned to the application program in the EIBRESP field. It is the responsibility of the user exit program to ensure that a correct value is placed here. It should be necessary to return only the NOTFND or QIDERR condition, but you are not restricted in doing so. |
| esm-eibresp2 | If your exit program returns a non-zero value in the field esm-eibresp, it must return a non-zero value in this field. The only values that your exit program needs to return are 1, 3, 5 or 8 for the NOTFND condition, or 1 for the QIDERR condition. This value is returned to the application in the EIBRESP2 field. |
| esm-eibrcode | If your exit returns a non-zero value in the field esm-eibresp, then it must place a hexadecimal value in this field. This value is returned to the application program in the EIBRCODE field. |
| esm-alter | If the application has requested the ALTER status for the named resource (field esm-arg-08-flag set), then the exit program must return a CVDA value of either ALTERABLE or NOTALTERABLE in this field. |
| esm-control | If the application has requested the CONTROL status for the named resource (field esm-arg-09-flag set), then the exit program must return a CVDA value of either CTRLABLE or NOTCTRLABLE in this field. |
| esm-read | If the application has requested the READ status for the named resource (field esm-arg-05-flag set), then the exit program must return a CVDA value of either READABLE or NOTREADABLE in this field. |
| esm-update | If the application has requested the UPDATE status for the named resource (field esm-arg-06-flag set), then the exit program must return a CVDA value of either UPDATABLE or NOTUPDATABLE in this field. |
Note: All character fields in the input parameter block are encoded in ANSI, even though they may have originated from an EBCDIC program. If you need the data in EBCDIC, then you will have to convert the data. For further information see the chapter .
When a QUERY SECURITY command is encountered the command is validated and may return one of a number of error conditions. If the command passes validation, the input fields are set up and control is passed to the user exit program. The user exit program may then itself perform some validation and reject the requests.
The following table shows the error conditions that can be returned:
| Error Condition (EIBRESP field) | Further information (EIBRESP2 field) | |
|---|---|---|
| INVREQ | 7 | LOGMESSAGE does not contain either LOG or NOLOG |
| 9 | RESID is invalid or filled with blanks | |
| 10 | The external security manager (ESM) is inactive or not present. This means that the user exit program is missing. | |
| LENGERR | 6 | The RESIDLENGTH value is not valid, that is, it is not in the range 1 through 246 |
| NOTFND | 2 | The RESTYPE value is not valid |
The following table shows the error conditions that you are most likely to need to check for in your exit program.
| Error Condition (EIBRESP field) | Further information (EIBRESP2 field) | |
|---|---|---|
| NOTFND | 1 | The RESID value is not valid |
| 3 | The RESID value for RESTYPE (SPCOMMAND) not valid. | |
| 5 | The RESCLASS is not defined to the external security manager (ESM). | |
| 8 | The resource is not protected. This is only returned when QUERY SECURITY is used with the RESCLASS option (and never occurs with RESTYPE). | |
| QIDERR | 1 | An indirect queue name associated with the given RESID is not found |
If any of these error codes are returned to an application program that does not provide error handling, the application abends.
Copyright © 2008 Micro Focus (IP) Ltd. All rights reserved.