HFSSEC Control Option

The CA Top Secret Control Option turns HFS security ON and OFF. This control option is set in the TSS PARMS startup member or can be dynamically set via a TSS MODIFY command.
The CA Top Secret Control Option turns HFS security ON and OFF. This control option is set in the TSS PARMS startup member or can be dynamically set via a TSS MODIFY command.
To determine the current active setting of HFSSEC, enter:
    Enables CA SAF HFS security. Normal z/OS UNIX security access validation is bypassed. This includes checking of file permission bits, superuser status
    and normal z/OS UNIX security services.
    Disables CA SAF HFS security. Normal z/OS UNIX security access validation is enabled. This includes checking of file permission bits, superuser status
    and normal z/OS UNIX security services.
Exit Processing
An exit point is provided for installation-specific processing. This exit is called for both an initialization function, where options involving pathname translation and user path processing can be selected, and a pathname translation function, where final modification to the pathname can be made before validation is performed.
The exit must be reentrant and capable of running AMODE(31) and RMODE(ANY). The exit name is SAFHFUSR and must be linked together with load module SAFHFSEC. A sample SMPE usermod to perform this is in CAIJCL member UD00001.
Upon entry to the exit, register R1 points to a list of addresses. The end of the list is indicated by the high order bit in the last full word.
Initialization Parameter Addresses
For an initialization function, the exit is passed the following parameter addresses:
  • +0
    The address of a single byte containing the character ‘I’ indicating that this is an initialization function.
  • +4
    The address of a 512-byte work area for the use of the exit program.
  • +8
    The address of a 255-byte field in which the user can return the path location where user directories are located. Upon input, this field contains hex zeros.
  • +12
    The address of a single byte which, when set to ‘Y’ by the exit, indicates that user ownership of files is in effect.
  • +16
    The address of a 256-byte translation table, which is used to translate certain special characters in a path name.
Exit Return Processing
When the exit returns a user directory path location, CA SAF HFS processing uses that path name to determine if the path name to be validated should be translated to a form such that the user ID of the owner of the path becomes the high-level qualifier of the path name. This allows HFS file rules to be written at the user level. The default is that no translation takes place for user directories.
If the exit returns the value 
 as the user directory path name location, and the file accessed is /u/user01/xfile, then the resource name validated is $$USER01.XFILE.When the exit returns the character ‘Y’ indicating that user ownership of files within one’s own directory is in effect, no validation is performed when the current user’s logonid matches that in the user directory.
This option is meaningless if a user directory path location is not also returned.
Example: access validation
In this example validation is bypassed when USER01 accesses file /u/user01/xfile:
TSS PER(USER01) HFSSEC($$%)                 ACCESS(UPDATE)
Character Translation Table
The supplied translate table is in a format acceptable as input to the assembler TR instruction. The default translate table translates all slash characters in a path name, with the exception of the leading slash, to a period character. Other special characters are translated into the dollar sign ($). These include characters that are used as masking characters in resource rules. If not translated, these characters could create undesired results. The special characters include the period, asterisk, dash, plus, blank, and quote.
The exit point can further modify any character in the table to meet special needs (with the exception of the slash character).
Path Name Translation Parameters
For a path name translation function, the exit is passed the following parameter addresses:
  • +0
    The address of a single byte containing the character ‘P’ indicating that this is a path name translation function.
  • +4
    The address of a 512-byte work area for the use of the exit program.
  • +8
    The address of a 255-byte field containing the resource name as modified by CA SAF HFS processing. This is the name that is used for validation. The exit can return a modified path name in this same field.
  • +12
    The address of a 1023-byte field containing the original unmodified path name.
The exit can use this exit function to make any specific modifications to the path name beyond that already performed by CA SAF HFS security processing.
CA SAF HFS ADD/PERMIT Generation Utility
A set of utility programs is provided to generate CA Top Secret commands used as a starter set of resource definitions and authorizations for new implementations. The HFS resource authorizations created give access based upon the file permission bits defined for groups and ‘other’ users. The rules give users the same default access to files they have when not running CA SAF HFS security. The generated authorizations must be modified to allow appropriate users greater access to the directory resources than that granted to the general user community. Because of the number of files that can be contained in the HFS the utility only covers the directories. File permissions can be added before running the REXX exec.
The HFS File System contains directories and files in a tree structure. In order to quickly add CA Top Secret security a set of procedures and utilities are provided.
File Protection Procedure
Use this procedure to protect your current file system:
  1. Run the OMVS “
    ” command in a batch TMP. Direct the output to a standard DASD file. This file must be allocated with RECFM=VB.
    Issue the 
     command from the OMVS shell, directing the output to a HFS file. The options
    must be specified (the character following the dash is a lower case letter ‘L’, not the number one). The file can then be copied into a MVS data set using the OGET command. For example:
    ls  -lRA  /  >>directory_information_file OGET ‘/directory_information_file’ ‘mvs.input.file’ The resulting file data should look similar to this: /:                                                             total 232                                                      drwx------   3 USER     OPENMVS        0 Jun  3  1998 JavaS390 drwxr-xr-x   4 USER                    0 May  7  1998 bin      drwx--x--x   2 USER     OPENMVS        0 Oct  1  1997 dev      drwxr-xr-x   8 USER     OPENMVS        0 Nov  4 17:05 etc      drwxr-xr-x   2 USER                    0 Jan 20  1998 lib      drwxrwxrwx   2 USER                    0 Jan 19 11:51 tmp      drwxr-xr-x   8 USER     OPENMVS        0 Jan 15 15:47 u        drwxr-xr-x  11 USER                    0 Jan 20  1998 usr                                                                     /JavaS390: total 16                                                       drwxrwxrwx   7 USER     ZEROGRP        0 Sep 25  1997 J1.1.1
  2. Run HFSPASS1. 
    This job reads the file from the previous step, creates and intermediate data set and then sort that data creating a file for the next step. 
    //        JOB //STEP1   EXEC PGM=HFSUTIL1,REGION=0M                                       //SYSABEND DD SYSOUT=*                                                      //SYSUDUMP DD SYSOUT=*                                                      //HFSINPUT DD DSN=????.????.????,DISP=SHR                                   //EXTRACT  DD DSN= SORT.INPUT,UNIT=3390, //        DISP=(NEW,CATLG,DELETE),SPACE=(TRK,(15,1),RLSE),                  //        DCB=(RECFM=FB,LRECL=300,BLKSIZE=6000)                             /*                                                                          //STEP2   EXEC PGM=SORT,REGION=0M                                           //SYSOUT  DD SYSOUT=*                                                       //SORTWK01  DD UNIT=3390,SPACE=(CYL,5)                                      //SORTWK02  DD UNIT=3390,SPACE=(CYL,5)                                      //SORTWK03  DD UNIT=3390,SPACE=(CYL,5)                                      //SORTWK04  DD UNIT=3390,SPACE=(CYL,5)                                      //SORTIN    DD DSN=SORT.INPUT,DISP=(OLD,DELETE,KEEP)                        //SORTOUT   DD DSN=SORT.OUTPUT,UNIT=3390,                                   //         DISP=(NEW,CATLG,DELETE),SPACE=(TRK,(15,1),RLSE),                 //         DCB=(RECFM=FB,LRECL=300,BLKSIZE=6000),VOL=SER=SCAC16             //SYSIN     DD *                                                             SORT FIELDS=(1,264,CH,A)                                                   /*     
  3. (Optional) Alternatively, the input file from the first step can point directly to the directory information file created from the 
    If using this format, the LRECL value specified in the JCL must be at least as large as the largest record in the file. The BLKSIZE value should be a value at least 8 greater than the LRECL. The PATH name must be the full path name of the file containing the directory information. A sample statement follows:
    //HFSINPUT  DD   PATH=‘/directory_information_file’, //               PATHOPTS=(ORDONLY),FILEDATA=TEXT, //               RECFM=VB,LRECL=nnn,BLKSIZE=nnn
  4. Edit the file created in step 2:
    a. At the beginning of the data set are records to build a /group profile cross-reference table. The formats of those records are:
    AAAAAAAA - xxxxxxxx 
    where AAAAAAAA is the name of an OMVS group
    Change xxxxxxxx to a profile to be used for any permissions needed by this group. In our example OPENMVS is the group and you must assign a profile name to “xxxxxxxx”.
    This is not a complete list of all groups, only those ACIDs that needs a specific permission given.
    b. After those records are several TSS ADD or TSS ADDTO commands. These are all of the ownership’s that are required for the conversion to meet with success. In these statements the xxxxxxxx (ACID name) needs to be modified to whatever ACID the client wants to own the specified resources. 
    OPENMVS  - xxxxxxxx                                                    TSS ADD(xxxxxxxx) HFSSEC(ROOT)                                         TSS ADD(xxxxxxxx) IBMFAC(BPX.CAHF)                                     TSS ADD(xxxxxxxx) HFSSEC(/bin)                                       TSS ADD(xxxxxxxx) HFSSEC(/dev)                                       TSS ADD(xxxxxxxx) HFSSEC(/etc)                                       TSS ADD(xxxxxxxx) HFSSEC(/lib)                                       TSS ADD(xxxxxxxx) HFSSEC(/opt)                                       TSS ADD(xxxxxxxx) HFSSEC(/samples)                                   TSS ADD(xxxxxxxx) HFSSEC(/tmp)                                       TSS ADD(xxxxxxxx) HFSSEC(/u)                                         TSS ADD(xxxxxxxx) HFSSEC(/usr)                                       TSS ADD(xxxxxxxx) HFSSEC(/JavaS390)                                  TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.ATTRIBUTES)         TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.AUDIT.FLAGS)        TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.FORMAT)             TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.GROUP)              TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.MODE.EGID)          TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.MODE.EUID)          TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.MODE.STICKY)        TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.MODE)               TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.OWNER)              TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.TIME)               TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.PRIORITY)                TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CREATE.EXTERNAL.LINK)           TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CREATE.LINK)                    TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.CREATE.SYMBOLIC.LINK)           TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.MOUNT)                          TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.PTRACE)                         TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.SET.PRIORITRY)                  TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.SET.RLIMIT)                     TSS PER(ALL) FOR(14) IBMFAC(BPX.CAHFS.UNMOUNT)                        TSS PER(ALL) HFSSEC(ROOT) ACCESS(READ)                                ALL     //bin                                                           ALL     //dev                                                           ALL     //etc                                                           ALL     //lib                                                           ALL     //opt
  5. Run HFSPASS2.
    HFSPASS2 reads the edited data set and produces a data set containing all the TSS commands to be executed. For example:
    //        JOB //STEP3   EXEC PGM=HFSUTIL2,REGION=0M                             //SYSABEND DD SYSOUT=*                                            //SYSUDUMP DD SYSOUT=*                                            //EXTRACT  DD DSN=SORT.OUTPUT,DISP=SHR                            //PRMOUT   DD DSN=TSS.CMDS,UNIT=3390,VOL=SER=SCAC16,              //         DISP=(NEW,CATLG,DELETE),SPACE=(TRK,(15,1),RLSE),       //         DCB=(RECFM=FB,LRECL=300,BLKSIZE=6000)                  Example 2.1  Output from the HFSUTIL2 TSS ADD(xxxxxxxx) HFSSEC(ROOT)                                    TSS ADD(xxxxxxxx) IBMFAC(BPX.CAHF)                                TSS ADDTO(xxxxxxxx) HFSSEC(/bin)                                  TSS ADDTO(xxxxxxxx) HFSSEC(/dev)                                  TSS ADDTO(xxxxxxxx) HFSSEC(/etc)                                  TSS ADDTO(xxxxxxxx) HFSSEC(/lib)                                  TSS ADDTO(xxxxxxxx) HFSSEC(/opt)                                  TSS ADDTO(xxxxxxxx) HFSSEC(/samples)                              TSS ADDTO(xxxxxxxx) HFSSEC(/tmp)                                  TSS ADDTO(xxxxxxxx) HFSSEC(/u)                                    TSS ADDTO(xxxxxxxx) HFSSEC(/usr)                                  TSS ADDTO(xxxxxxxx) HFSSEC(/JavaS390)                             TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.ATTRIBUTES)    TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.AUDIT.FLAGS)   TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.FORMAT)        TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.GROUP)         TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.MODE.EGID)     TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.MODE.EUID)     TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.MODE.STICKY)   TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.MODE)          TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.OWNER)         TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.FILE.TIME)          TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CHANGE.PRIORITY)           TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CREATE.EXTERNAL.LINK)      TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CREATE.LINK)               TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.CREATE.SYMBOLIC.LINK)      TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.MOUNT)                     TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.PTRACE)                    TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.SET.PRIORITRY)             TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.SET.RLIMIT)                TSS PERM(ALL) FOR(14) IBMFAC(BPX.CAHFS.UNMOUNT)                   TSS PERM(ALL) HFSSEC(ROOT) ACCESS(READ)                           TSS PERMIT(ALL) HFSSEC(/bin) ACCESS(READ,EXEC)                    TSS PERMIT(ALL) HFSSEC(/dev) ACCESS(EXEC)                         TSS PERMIT(ALL) HFSSEC(/etc) ACCESS(READ,EXEC)                    TSS PERMIT(ALL) HFSSEC(/lib) ACCESS(READ,EXEC)                    TSS PERMIT(ALL) HFSSEC(/opt) ACCESS(READ,EXEC)                    TSS PERMIT(ALL) HFSSEC(/samples) ACCESS(READ,EXEC)   
  6. Run REXX exec to execute the commands in the data set.
    /*   REXX   */                                                        /*                                                                         This EXEC will have as input a dataset name and will read            that dataset and issue the TSS commands in it.                   */               arg dsn .                  /*  get data set name                 */   if dsn = ‘‘ then dsn = ‘????.?????.????’                             ‘ALLOC FI(PERMIN) DS(‘‘‘dsn’’’) SHR REUSE VOL(??????)’                eof = ‘no’                                                            do while eof = ‘no’                                                     ‘execio 1 diskr PERMIN’                                               if rc = 2                                                                then do                                                                  eof = ‘yes’                                                           end                                                                else do                                                                  pull record                                                           say ‘Record is: ‘ record                                              record                                                                end                                                           end                                                                     ‘execio 1 diskr permin ( finis’                                       ‘FREE FI(PERMIN)’                                                   exit 0