The data set services authorization exit is loaded by a data set services subtask and is called synchronously by the subtask. The exit can issue WAIT or other SVCs without impacting your product region's main task.
Review the source code for the sample data set services authorization exit NMDSSCHK and use it as a guide to writing your own exit.
The exit load module must be link edited as AMODE 24, RMODE 24. The exit procedure can be coded as reentrant; however, this is not required because an explicit load is performed for each task using the exit. The exit is always called in 24-bit address mode.
There are three main types of calls made to the exit:
Check the DSSCFUNC field to determine the type of call being made.
The exit is loaded separately by each invocation of the Data Services subtask. For example, a subtask is created to allocate or free a data set, or to open a data set, and so on.
The exit receives (per subtask invocation) one initialization call, possibly one or more logical function calls, and possibly one termination call. For example, copying a data set from A to B would result in the logical calls shown below:
ALLOC Atask init
ALLOC AALLOC call
ALLOC Atask terminate
ALLOC Btask init
ALLOC BALLOC call
ALLOC Btask terminate
READ A task init
READ A open check
WRITE Btask init
WRITE Bopen check
READ A task terminate
WRITE Btask terminate
FREE A task init
FREE A ALLOC call
FREE A task terminate
FREE B task init
FREE B ALLOC call
FREE B task terminate
If the exit is defined as reentrant you can use the DSSCXCOR field to anchor any private storage required by the subtask.
Note: Do not use shared (SP 50) storage as an exit work area.
On entry to the exit, Register 1 contains the address of a parameter list area that is used to pass information to the exit. This communication area is mapped by the $NMDSSCK macro, that is distributed with your product. This macro provides a DSECT expansion to perform mapping and contains detailed information on the contents of each field.
Standard module linkage conventions apply; on entry, the exit must save the contents of all registers (Register 13 contains the address of a save area that can be used by the exit) and on exit all registers must be restored to the value they had on entry with the exception of Register 15 that should contain a return code relevant to the function call.
This call allows the exit to perform any initialization required. This could include authorizing the subtask against the authority level of the user. This call is not specific to any request from the user: logical function calls identify the functions that have been requested by a user and you can perform more specific processing for these calls.
The parameter area passed to the exit contains the user ID of the user, any User Token or Security Exit Correlator associated with the user (drawn from the main security exit, if one is being used) and information about the region in which the exit is running (for example, the NMID).
The exit must return with Register 15 set to a return code that indicates the success or failure of exit initialization. A return code can be set to indicate that no more security processing is required for the function.
The following return codes are allowed for this call:
Indicates that exit initialization completed successfully.
Indicates that exit initialization completed successfully. No more logical function calls are required for this usernote that the termination call is still performed, however.
Indicates that exit initialization failed.
If Register 15 is set to 8, you can use the DSSCLMSG and DSSCTMSG fields to return a message indicating the reason for the failure. See the $NMDSSCK macro for full details. If no message is returned, data set services sets a default message. The message returned by the exit is recorded on the activity log.
If you set return code 4 on initialization, this means that the host does not need to participate on any subsequent logical function authorization.
You might do this, for example, if you issue a RACINIT during initialization to register the subtask as relating to a specific user ID (that is, when you have a security exit installed). In this case, for example, an OPEN DATASET call would result in an S913 OPEN ABEND since RACF does the security checking.
Note: Data set services handles this situation correctly.
If you set return code 0, but still connect the subtask to the security system, you can do additional checking on some calls (for example, rename PDS member) that the security system does not specifically check.
This call represents a function that has been requested by the user. For example, a data set allocation request or a request to open a data set. The DSSCTYPE field is used to indicate the function to be performed.
The parameter area passed to the exit contains all information passed on the exit initialization call as well as any specific information requested by the user for the function. For example, if the call is for an allocation request the data set name, disposition, volume name, and so on, might be available. The $NMDSSCK macro contains a full description of each logical function call and the parameters that are passed on each call.
The exit can return with Register 15 set to a return code that indicates whether the function is permitted.
The following return codes are allowed for this call:
Indicates that the function is authorized.
Indicates that the function is not authorized.
If Register 15 is set to 4, a message indicating the reason for the failure can be returned using the DSSCLMSG and DSSCTMSG fields. See the $NMDSSCK macro for full details. If no message is returned by the exit, data set services sets a default message. The message returned by the exit is recorded on the activity log.
This call allows the exit to clean up any allocated storage areas and, if applicable, break the connection with any security subsystem that is being used. The exit load module is deleted from storage on return from this call.
Note: This call may not occur. If, for example, an NCL process using data set services is flushed, the subtask(s) are force detached. You should be aware of this and allocate any private storage in a non-shared subpool (this can include subpool SP0 but not SP50), which results in the storage being automatically freed.
The parameter passed to the exit contains all information passed on the exit initialization call. Register 15 must contain 0 on return from this call.