JCL Enhanced Security Checks

Note: The following applies to native COBOL applications only.

In release 9.0, the JCL engine has been enhanced to provide increased security when running programs. In the past, built programs were placed in a location identified as the JES Program Path or in a location that was identified in the catalog as a Dynamic PDS and used as the STEPLIB or JOBLIB in a job. You can still use these locations and they will work without any changes to your existing configuration settings.

However, it is now possible to increase the security by limiting the locations that any main utility and user programs may be loaded from to a set of identified datasets. You can also restrict who has access to change those datasets. These changes make it difficult for a malicious program to be picked up and used just because it is in a location that is on the JES Program Path or in a Dynamic PDS.

If you continue to use the previous configuration, you will receive some warning messages indicating that programs may not be loaded from certain locations if the enhanced security is enabled. These give you a guide to what you may need to change when moving to a higher level of security to protect your system.

Starting with 9.0, there are two new levels of security available:

The search for the program to load and the checks for access to that program use the alias of the program (if one is set). This ensures that if the alias of, for example, IDCAMS is changed from MFJAMS to MYPROG the search and checks are made for MYPROG. The JES Program Path for programs other than the main program called from the JCL job may still be used and programs will still be loaded from there. The loading and check is against the program identified in the JCL job. As such, each program should appear as a separate entry in a PO. The PC-DSN of the entry should point to the actual program to load. If that program makes calls to other programs, those programs may be in the STEPLIB, JOBLIB, SYS1.LNKLIB or the JES Program Path.

Important: Only approved users (Administrators) should be granted ALTER access (for the DATASET resource class) to the POs that hold programs to be loaded. This ensures that the contents might not be changed by a malicious user.

Also, the JOBLIB and STEPLIB (the private libraries) can add locations for loading programs, but when they are used, EXECUTE access are checked on the datasets. Take care when granting EXECUTE access to users on broad matching DATASET rules.

The PDS that hold programs must be disk-based, even when running with data hosted in a database. The system cannot load programs from a database location.

Example

The jcl-symbols example is available in the Mainframe\JCL\Classic subfolder (Windows) in your product samples' location, and in $COBDIR/demo (UNIX). The INITSYS.JCL, INITSYS2.JCL, and MOVEPGMS.JCL files in the sample can be used to set up the libraries for holding system programs, and to move any built modules into those libraries. Check the sample's readme file for more details.

This is how you can run the example:

  1. In ESCWA, create a JCL-enabled region.
  2. Compile the programs, and add them into the JES Program Path location.

    The MOVEPGMS.JCL looks for the programs in /home/sysadmin/libs/ (UNIX) but any location identified on the JES Program Path will work.

  3. Start the region.

    When you start it for the first time, a warning message will be written to the console log that indicates that there are no SYS1.LNKLIB entries:

    JES000067W JES Validation - 0 SYS1.LNKLIB entries.
  4. Execute INITSYS.JCL.

    This creates the symbols and a number of SYS1.PARMLIB members that describe the program datasets to load at system startup.

  5. Execute INITSYS2.JCL to create those datasets.

    A listing of SYS1.LNKLIB now shows four datasets - SYS1.PROGLIB, SYS2.LNKLIB, MFI01.MFITEST.LIB and SYS2.U30LIB.

    Note that SYS1.MFTEST.LIB(TEST1) which is specified in SYS1.PARMLIB(LNKLST02) does not appear because the member(TEST1) has not yet been created. Similarly, other datasets that might be listed in the SYS1.LNKLIB concatenation do not appear if they do not also exist in the catalog. You can create them, and populate them with load modules later on.

  6. Execute the SYMBOL6.JCL sample job. Look at the JESYSMSG for the job.

    You can see messages that state where each utility program was loaded from, including a message that the program CALLMFJZ could not be found in the private libraries and SYS1.LNKLIB. There is also a message listing the libraries:

    JCLCM0305W Failed to find program CALLMFJZ in private libraries and SYS1.LNKLIB. 
    JCLCM0306I Number of SYS1.LNKLIB entries:         3. 
    JCLCM0307I SYS1.LNKLIB : SYS1.PROGLIB,SYS2.LNKLIB,MFI01.MFITEST.LIB.

    However, because the higher security level has not been set the system goes on to look on the JES Program Path for the program, and finds it:

    JCLCM0303I Program CALLMFJZ loaded from library SYS2.LOADLIB
    JCLCM0199I Program CALLMFJZ  is COBOL ANS85 ASCII  Big-Endian    NOAMODE.

    You can use MOVEPGMS.JCL to copy programs from the build location into the PO datasets.

    In the example job, the DEF1 dataset is defined as a dynamic PDS that has all *.dll files (Windows) or *.so programs (UNIX) in the /home/sysadmin/libs/ folder as its members. STEP10 uses the MFPOADD utility to copy some members of the Dynamic PDS into the standard PO, SYS1.PROGLIB, which has been identified as a system program library. MFPOADD is a variant of IEBCOPY (MFJCOPY) and will accept IEBCOPY control statements as given in the example steps in MOVEPGMS.JCL.

  7. Execute MOVEPGMS.JCL to move the programs into the locations defined in INITSY2.JCL, after first altering the location of the DEF1 temporary dynamic PDS to the location in which you have put your built program.
  8. Make sure your programs are now in the SYS1.PROGLIB dataset. They should be visible in the catalog listing.

    If running on UNIX, you might need to set the program permissions to be executable as these may have been lost in the copy from the original location.

  9. If you run SYMBOL6.JCL again, you should now see that CALLMFJZ is now loaded from SYS1.PROGLIB.
  10. Stop the region, and add the following entry to the ES Configuration section in the region definition:
    [ES-Environment]
    ES_JES_HIGHER_SECURITY_LEVEL=2
  11. Start the region, and look at the console.log.

    You should see the following messages:

    ES000067I JES Validation -         5 SYS1.LNKLIB entries. 
    JES000068I SYS1.LNKLST: SYS1.PROGLIB,SYS2.LNKLIB,MFI01.MFITEST.LIB,SYS1.MFTEST.LIB(TEST1),SYS2.U30LIB

    These show that there are five entries in the SYS1.LNKLIB concatenation. Note that not all of these entries exist in the catalog as can be seen by doing an IDCAMS LISTCAT ENTRIES(SYS1.LNKLIB).

  12. Execute SYMBOL6.JCL again.

    The following messages appear:

    Program IEBGENER (MFJGENER) loaded from library SYS1.LOADLIB
    Program CALLMFJZ loaded from library SYS1.PROGLIB
  13. From the catalog view, delete the CALLMFJZ member from the SYS1.PROGLIB PO, and run SYMBOL6.JCL again.

    You should receive the following message:

    Failed to find program CALLMFJZ in private libraries and SYS1.LNKLIB

    Even though the program might still be on the JES Program Path, it will not be used unless it is in one of the defined system libraries or a private JOBLIB or STEPLIB library.

    In the program load messages above, the symbolic name SYS1.LOADLIB indicates that the program has been loaded from the product. SYS2.LOADLIB would indicate the JES Program Path.