### SAF Consideration

Beginning with version 5.1.21 a lot of additional checks against a System authorization facility (SAF) can be activated. These SAF support gives for example an RACF administrator on z/OS the possibility to activate different security policies and control a lot of resources used by FLAM.

- Several security policies (disable PCAP, ensure finger prints, minimal key length, ...)
- CLE/P parameter strings (complete control about the functionality)
- Control access to pre- and post-processing commands (executed on remote or local systems)
- To secure all service provider interfaces (FAVE, FCPE, FKME)
  - Control to which AV daemon the clear data is transfered
- Control access to complete URLs containing connection, path, filename and member
  - Allow to protect members of PDS/E, ZIP or FLAM archives
- Secure SSH connections (Control user, server and port)
- PGP key management (User ID to import, export, generate, delete)
- Control access to PGP user and key IDs for signing and key exchange
- Control methods, algorithms, modes and a lot more of the en/decryption component
- Activate and enforce additional SMF logging (e.g. record type 119 (SSH))
- All feature codes of the FLAM license module

The complete SAF setup is documented in the corresponding install.txt and can be simply extended on user request. For z/OS with RACF we recommend at minimum the definitions below (be careful with this example, we are no RACF specialists):

        //S01      EXEC PGM=IKJEFT01,DYNAMNBR=75,TIME=100,REGION=6M
        //SYSPRINT DD SYSOUT=*
        //SYSTSPRT DD SYSOUT=*
        //SYSTERM  DD DUMMY
        //SYSUADS  DD DSN=SYS1.UADS,DISP=SHR
        //SYSLBC   DD DSN=SYS1.BRODCAST,DISP=SHR
        //SYSTSIN  DD *
        RDEFINE CDT +
                $FLAM +
                CDTINFO(CASE(ASIS)        /* mixed case profile names */ +
                        DEFAULTRC(4)      /* default                  */ +
                        DEFAULTUACC(NONE) /* default                  */ +
                        FIRST(ALPHA)      /* profile name first char  */ +
                        GENERIC(ALLOWED)  /* default                  */ +
                        KEYQUALIFIERS(0)  /* default                  */ +
                        MAXLENGTH(246)    /* maximum prof name length */ +
                        OPERATIONS(NO)    /* default                  */ +
                        OTHER(ALPHA,      /* prof name allows A-Z,a-z */ +
                              NUMERIC,    /*                  0-9     */ +
                              NATIONAL,   /*                  #,@,$   */ +
                              SPECIAL)    /* all except blank ( ) , ; */ +
                        POSIT(202)        /* in user range 128-527    */ +
                        RACLIST(ALLOWED)  /* setr raclist allowed     */ +
                        SECLABELSREQUIRED(NO) /* default              */ +
                        SIGNAL(NO)        /* default (no ENF signals) */ +
                       )
        SETROPTS CLASSACT(CDT)
        SETROPTS RACLIST(CDT)
        SETROPTS RACLIST(CDT) REFRESH
        //S02      EXEC PGM=IKJEFT01,DYNAMNBR=75,TIME=100,REGION=6M
        //SYSPRINT DD SYSOUT=*
        //SYSTSPRT DD SYSOUT=*
        //SYSTERM  DD DUMMY
        //SYSUADS  DD DSN=SYS1.UADS,DISP=SHR
        //SYSLBC   DD DSN=SYS1.BRODCAST,DISP=SHR
        //SYSTSIN  DD *
        PERMIT $FLAM CLASS(CDT) RESET     /* clear permit list        */
        RALTER CDT   $FLAM OWNER(SYS1)    /* change ownership         */
        SETROPTS RACLIST(CDT) REFRESH
        //S03      EXEC PGM=IKJEFT01,DYNAMNBR=75,TIME=100,REGION=6M
        //SYSPRINT DD SYSOUT=*
        //SYSTSPRT DD SYSOUT=*
        //SYSTERM  DD DUMMY
        //SYSUADS  DD DSN=SYS1.UADS,DISP=SHR
        //SYSLBC   DD DSN=SYS1.BRODCAST,DISP=SHR
        //SYSTSIN  DD *
        SETROPTS GENERIC($FLAM)
        RDEFINE $FLAM +
                **                        /* cover all entities       */ +
                OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.MUSTDEF OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.POLICIES OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.SMF.LOGGING OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.CLP.CONTROL OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.CMD.CONTROL OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.AVE.CONTROL OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.CPE.CONTROL OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.KME.CONTROL OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.EDC.CONTROL OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.FIO.CONTROL OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.FL4.CONTROL OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.SSH.CONNECT OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.PGP.KEYMNGM OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.PGP.USERID OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM GLOBAL.PGP.KEYID OWNER(SYS1) UACC(NONE)

        RDEFINE $FLAM POLICY.LOW.ENTROPY OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.LOG.INPUT OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.SSH.PCAP.ALLOWED OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.SSH.WEAK.HOSTKEY.CHECK.ALLOWED OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.SSH.CUSTOM.HOSTKEY.ALLOWED OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.SSH.CUSTOM.KNOWN.HOST.FILE.ALLOWED OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.KEY.GENERATE.PGP.EXPIRD.REQIRED OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.KEY.GENERATE.PGP.ALGO.RSA.KEYLEN OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.KEY.GENERATE.PGP.ALGO.DSA.ALLOWED OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.KEY.IMPORT.PGP.KIDVER OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.KEY.IMPORT.PGP.DOUBLE.KIDS OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.PGP.PWD OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.PGP.PWD.LEN.ENC OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.PGP.PWD.LEN.DEC OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.PGP.ENFORCE.ENCRYPTION OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.PGP.ENFORCE.INTEGRITY OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.PGP.ENFORCE.SIGNING OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.EDC.PARM.FILE.ALLOWED OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.EDC.KEY.PRINT.ALLOWED OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.EDC.KEY.INVERSE.ALLOWED OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.EDC.NO.HEADER.ALLOWED OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.EDC.NO.SALT.ALLOWED OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.SYM.KEY.LEN.ENC OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.SYM.KEY.LEN.DEC OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.SYM.PWD.LEN.ENC OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM POLICY.SYM.PWD.LEN.DEC OWNER(SYS1) UACC(NONE)

        RDEFINE $FLAM FAVELIB.libfave OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM FAVEFUC.CLAMAVC OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM FAVEPAR.clamd.limes.de:3310 OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM FAVEIPH.clamd.limes.de OWNER(SYS1) UACC(NONE)
        RDEFINE $FLAM FAVEIPS.3310 OWNER(SYS1) UACC(NONE)

        PERMIT  **   CLASS($FLAM) RESET   /* clear permit list (optional)*/
        PERMIT  GLOBAL.MUSTDEF CLASS($FLAM) ID(*) ACC(CONTROL)
    /*  PERMIT  GLOBAL.POLICIES CLASS($FLAM) ID(*) ACC(NONE)      ACTIVE */
        PERMIT  GLOBAL.SMF.LOGGING CLASS($FLAM) ID(*) ACC(ALTER)/*INACTIV*/
        PERMIT  GLOBAL.CLP.CONTROL CLASS($FLAM) ID(*) ACC(ALTER)/*INACTIV*/
        PERMIT  GLOBAL.CMD.CONTROL CLASS($FLAM) ID(*) ACC(ALTER)/*INACTIV*/
    /*  PERMIT  GLOBAL.AVE.CONTROL CLASS($FLAM) ID(*) ACC(NONE)   ACTIVE */
        PERMIT  GLOBAL.CPE.CONTROL CLASS($FLAM) ID(*) ACC(ALTER)/*INACTIV*/
        PERMIT  GLOBAL.KME.CONTROL CLASS($FLAM) ID(*) ACC(ALTER)/*INACTIV*/
        PERMIT  GLOBAL.EDC.CONTROL CLASS($FLAM) ID(*) ACC(ALTER)/*INACTIV*/
        PERMIT  GLOBAL.FIO.CONTROL CLASS($FLAM) ID(*) ACC(ALTER)/*INACTIV*/
    /*  PERMIT  GLOBAL.FL4.CONTROL CLASS($FLAM) ID(*) ACC(ALTER)  ACTIVE */
        PERMIT  GLOBAL.SSH.CONNECT CLASS($FLAM) ID(*) ACC(ALTER)/*INACTIV*/
        PERMIT  GLOBAL.PGP.KEYMNGM CLASS($FLAM) ID(*) ACC(ALTER)/*INACTIV*/
        PERMIT  GLOBAL.PGP.USERID CLASS($FLAM) ID(*) ACC(ALTER) /*INACTIV*/
        PERMIT  GLOBAL.PGP.KEYID CLASS($FLAM) ID(*) ACC(ALTER)  /*INACTIV*/

    /*  PERMIT  POLICY.SSH.PCAP.ALLOWED CLASS($FLAM) ID(*) ACC(NONE)*/
        PERMIT  POLICY.SSH.WEAK.HOSTKEY.CHECK.ALLOWED CLASS($FLAM) ID(*) ACC(UPDATE)
        PERMIT  POLICY.SSH.CUSTOM.HOSTKEY.ALLOWED CLASS($FLAM) ID(*) ACC(UPDATE)
        PERMIT  POLICY.SSH.CUSTOM.KNOWN.HOST.FILE.ALLOWED CLASS($FLAM) ID(*) ACC(UPDATE)
        PERMIT  POLICY.KEY.GENERATE.PGP.EXPIRD.REQIRED CLASS($FLAM) ID(*) ACC(UPDATE)
        PERMIT  POLICY.KEY.GENERATE.PGP.ALGO.RSA.KEYLEN CLASS($FLAM) ID(*) ACC(UPDATE)
    /*  PERMIT  POLICY.KEY.GENERATE.PGP.ALGO.DSA.ALLOWED CLASS($FLAM) ID(*) ACC(NONE)*/
        PERMIT  POLICY.KEY.IMPORT.PGP.KIDVER CLASS($FLAM) ID(*) ACC(UPDATE)
    /*  PERMIT  POLICY.KEY.IMPORT.PGP.DOUBLE.KIDS CLASS($FLAM) ID(*) ACC(READ)*/
        PERMIT  POLICY.PGP.PWD CLASS($FLAM) ID(*) ACC(ALTER)
        PERMIT  POLICY.PGP.PWD.LEN.ENC CLASS($FLAM) ID(*) ACC(CONTRL)
        PERMIT  POLICY.PGP.PWD.LEN.DEC CLASS($FLAM) ID(*) ACC(ALTER)
    /*  PERMIT  POLICY.PGP.ENFORCE.ENCRYPTION CLASS($FLAM) ID(*) ACC(NONE)*/
    /*  PERMIT  POLICY.PGP.ENFORCE.INTEGRITY CLASS($FLAM) ID(*) ACC(NONE)*/
        PERMIT  POLICY.PGP.ENFORCE.SIGNING CLASS($FLAM) ID(*) ACC(ALTER)
        PERMIT  POLICY.EDC.PARM.FILE.ALLOWED CLASS($FLAM) ID(*) ACC(UPDATE)
        PERMIT  POLICY.EDC.KEY.PRINT.ALLOWED CLASS($FLAM) ID(*) ACC(UPDATE)
    /*  PERMIT  POLICY.EDC.KEY.INVERSE.ALLOWED CLASS($FLAM) ID(*) ACC(NONE)*/
        PERMIT  POLICY.EDC.NO.HEADER.ALLOWED CLASS($FLAM) ID(*) ACC(UPDATE)
        PERMIT  POLICY.EDC.NO.SALT.ALLOWED CLASS($FLAM) ID(*) ACC(READ)
        PERMIT  POLICY.EDC.STATIC.KEY.ALLOWED CLASS($FLAM) ID(*) ACC(ALTER)
        PERMIT  POLICY.EDC.STATIC.IV.ALLOWED CLASS($FLAM) ID(*) ACC(UPDATE)
        PERMIT  POLICY.SYM.KEY.LEN.ENC CLASS($FLAM) ID(*) ACC(UPDATE)
        PERMIT  POLICY.SYM.KEY.LEN.DEC CLASS($FLAM) ID(*) ACC(UPDATE)
        PERMIT  POLICY.SYM.PWD.LEN.ENC CLASS($FLAM) ID(*) ACC(CONTRL)
        PERMIT  POLICY.SYM.PWD.LEN.DEC CLASS($FLAM) ID(*) ACC(ALTER)

        PERMIT  FAVELIB.libfave CLASS($FLAM) ID(*) ACC(READ)
        PERMIT  FAVEFUC.CLAMAVC CLASS($FLAM) ID(*) ACC(READ)
        PERMIT  FAVEPAR.clamd.limes.de:3310 CLASS($FLAM) ID(*) ACC(READ)
        PERMIT  FAVEIPH.clamd.limes.de CLASS($FLAM) ID(*) ACC(READ)
        PERMIT  FAVEIPS.3310 CLASS($FLAM) ID(*) ACC(READ)

        SETROPTS CLASSACT($FLAM)
        SETROPTS RACLIST($FLAM)
        SETROPTS RACLIST($FLAM) REFRESH

First (in step 1 and 2) the general resource class $FLAM must be setup. The last step defines the rights for the certain entities. The recommendation defines all the policies and enable anti virus scanning only with the defined ClamAV daemon (DSN must be adjusted).

The entities for command execution or parameter string can include whitespace or one of the other 4 invalid characters '(),;'. If such an invalid character is encountered in an entity string, it is replaced by an underscore '_' before the SAF check. For example the PDS(E) 'HLQ.PO(HUGO)' results in the resource name 'FIOURL.HLQ.PO_HUGO_'. The global pre-write pre-processing command 'ls -l' results in the resource name 'CMD.PRE.WRITE.GLOBAL.ls_-l'.