/* REXX */
/*trace r?*/
Signal On NoValue
Call On Error
Signal On Failure
Signal On Syntax
Parse source opsys . exec_name .
 
/*********************************************************************/
/* 04/23/2023 CL Fenton created from REXCRTS.  To provide            */
/*            automation for RACF-ES-000560 and RACF-OS-000210 to    */
/*            evaluate NOWARNING and UACC(NONE), TMS-3563,           */
/*            TMS-3562.                                              */
/* 10/22/2024 CL Fenton Changes made to exclude resource classes     */
/*            DIGTCERT and NODES from RACF-OS-000210 evaluation      */
/*            for RACF0800, SCTASKU0231892.                          */
/* 01/29/2026 CL Fenton Changes made in output messages.             */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*********************************************************************/
pgmname = "CARC0006 01/29/26"
CONSLIST = "OFF"                  /* DEFAULT IS OFF                  */
COMLIST  = "OFF"                  /* DEFAULT IS OFF                  */
SYMLIST  = "OFF"                  /* DEFAULT IS OFF                  */
TERMMSGS = "OFF"                  /* DEFAULT IS OFF                  */
CACC1000 = "CACC1000"             /* SELECT SECURITY CHECK PGM       */
TEST     = "OFF"                  /* Finding Msgs (OFF|MOD|FINDING)  */
TRACE    = "OFF"                  /* TRACE ACTIONS AND ERRORS        */
 
sysprompt = "OFF"                 /* CONTROL NOPROMPT                */
sysflush = "OFF"                  /* CONTROL NOFLUSH                 */
sysasis = "ON"                    /* CONTROL ASIS - caps off         */
Numeric digits 10                 /* default of 9 not enough         */
/* initialize table counters    */
duacc         = 0      /* 0400 record type for dataset UACC          */
ruacc         = 0      /* 0500 record type for resoure UACC          */
dwarn         = 0      /* 0400 record type for dataset WARNING       */
rwarn         = 0      /* 0500 record type for resoure WARNING       */
lminit_pdidd_rc  = "N/A"
lmopen_pdidd_rc  = "N/A"
lmclose_pdidd_rc = "N/A"
lmfree_pdidd_rc  = "N/A"
maxcc         = 0
return_code   = 0
 
Arg OPTION
do until OPTION = ""
  parse var OPTION key"("val")" OPTION
  val = strip(val,"b","'")
  val = strip(val,"b",'"')
  optcmd = key '= "'val'"'
  interpret optcmd
  end
 
return_code = 0
If trace = "ON" then do            /* TURN messages on          */
  termmsgs = "ON"                  /* CONTROL MSG               */
  comlist = "ON"                   /* CONTROL LIST              */
  conslist = "ON"                  /* CONTROL CONLIST           */
  symlist = "ON"                   /* CONTROL SYMLIST           */
  end
 
If CONSLIST = "ON" | COMLIST = "ON" | SYMLIST = "ON" | TRACE = "ON",
  then Trace ?r
 
syssymlist = symlist          /* CONTROL SYMLIST/NOSYMLIST */
sysconlist = conslist         /* CONTROL CONLIST/NOCONLIST */
syslist = comlist             /* CONTROL LIST/NOLIST       */
sysmsg = termmsgs             /* CONTROL MSG/NOMSG         */
Address ISPEXEC
"CONTROL NONDISPL ENTER"
"CONTROL ERRORS RETURN"
"VPUT (CONSLIST COMLIST SYMLIST TERMMSGS) ASIS"
zispfrc = 0
"VPUT (ZISPFRC) SHARED"
 
return_code = 0
 
"SELECT CMD("cacc1000 "ACP)"
"VGET (ACPNAME ACPVERS) ASIS"
 
return_code = 0
"lminit dataid(pdidd) ddname(pdidd)"
lminit_pdidd_rc = return_code
return_code = 0
"lmopen dataid("pdidd") option(output)"
lmopen_pdidd_rc = return_code
 
 
/***********************************************************/
/* Main Driver                                             */
/* dbufile is IRRDBU00 unloaded dataset                    */
/***********************************************************/
Address TSO "EXECIO * DISKR dbufile (stem dbfle. FINIS"
Say pgmname "Total Records in unloaded dataset ==> "dbfle.0
Say pgmname "Search Completed . . ."
do a = 1 to dbfle.0
  Rec_type = substr(dbfle.a,1,4)
  if Rec_type = 0400 then,
    call Process400
  if Rec_type = 0500 then,
    call Process500
  end         /*  do a  */
 
Say pgmname "Dataset profiles with WARNING        "right(dwarn,4)
Say pgmname "Dataset profiles without UACC(NONE)  "right(duacc,4)
Say pgmname "Resource profiles with WARNING       "right(rwarn,4)
Say pgmname "Resource profiles without UACC(NONE) "right(ruacc,4)
 
pdi = "RACF0790"
If dwarn = 0 &,
   rwarn = 0 then
  queue "Not a Finding"
 
if dwarn > 0 then do
  queue "The following dataset profiles specify WARNING."
  queue " "
  do x = 1 to dwarn
    parse var dwarntab.x profile gen warn .
    if gen = "YES" then,
      gen = " (G)"
    else,
      gen = ""
    queue "    " profile""gen "WARNING="warn
    end
  queue " "
  end
if rwarn > 0 then do
  queue "The following resource profiles specify WARNING."
  queue " "
  do x = 1 to rwarn
    parse var rwarntab.x profile rescl gen warn .
    if gen = "YES" then,
      gen = " (G)"
    else,
      gen = ""
    queue "    " left(rescl,11) profile""gen "WARNING="warn
    end
  queue " "
  end
call process_queued_pdi
 
pdi = "RACF0800"
If duacc = 0 &,
   ruacc = 0 then
  queue "Not a Finding"
 
if duacc > 0 then do
  queue "The following dataset profiles do not specify UACC(NONE)."
  queue " "
  do x = 1 to duacc
    parse var duacctab.x profile gen uacc .
    if gen = "YES" then,
      gen = " (G)"
    else,
      gen = ""
    queue "    " profile""gen "UACC("uacc")"
    end
  queue " "
  end
if ruacc > 0 then do
  queue "The following resource profiles do not specify UACC(NONE)."
  queue " "
  do x = 1 to ruacc
    parse var ruacctab.x profile rescl gen uacc .
    if gen = "YES" then,
      gen = " (G)"
    else,
      gen = ""
    queue "    " left(rescl,11) profile""gen "UACC("uacc")"
    end
  queue " "
  end
call process_queued_pdi
 
 
/*******************************************/
/* ERROR EXIT                              */
/*******************************************/
ERR_EXIT:
If maxcc >= 16 | return_code > 0 then do
  "VGET (ZISPFRC) SHARED"
  If maxcc > zispfrc then
    zispfrc = maxcc
  Else
    zispfrc = return_code
  "VPUT (ZISPFRC) SHARED"
  Say pgmname "ZISPFRC =" zispfrc
  end
 
return_code = 0
"lmclose dataid("pdidd")"
lmclose_pdidd_rc = return_code
return_code = 0
"lmfree dataid("pdidd")"
lmfree_pdidd_rc = return_code
/*                                                            */
If TERMMSGS = "ON" then do
  Say "==============================================================="
  Say pgmname "LMINIT_PDIDD_RC                   "lminit_pdidd_rc
  Say pgmname "LMOPEN_PDIDD_RC                   "lmopen_pdidd_rc
  Say pgmname "LMCLOSE_PDIDD_RC                  "lmclose_pdidd_rc
  Say pgmname "LMFREE_PDIDD_RC                   "lmfree_pdidd_rc
  Say "==============================================================="
  end
 
Exit 0
 
 
/*******************************************/
/*  SYSCALL SUBROUTINES                    */
/*******************************************/
process400:
dbfle.a = dbfle.a
UCN_0400 = substr(dbfle.a,6,44)    /* 246-Char resource profile    */
grbd_gen = substr(dbfle.a,58,3)    /* generic - YES/NO             */
grbd_uacc = substr(dbfle.a,129,8)  /* uacc - ALTER/CONTROL/UPDATE/ */
                                   /* READ/EXECUTE/NONE            */
grbd_warn = substr(dbfle.a,484,3)  /* warning - YES/NO             */
If grbd_warn = "YES" then do
/*If grbd_warn = "YES" |,
   dwarn = 0 then do*/
  dwarn = dwarn + 1
  dwarntab.dwarn = UCN_0400 grbd_gen grbd_warn
  end
If grbd_uacc <> "NONE" then do
/*If grbd_uacc <> "NONE" |,
   duacc = 0 then do*/
  duacc = duacc + 1
  duacctab.duacc = UCN_0400 grbd_gen grbd_uacc
  end
return
 
 
process500:
dbfle.a = dbfle.a
UCN_0500 = substr(dbfle.a,6,246)   /* 246-Char resource profile    */
grbd_rescl = substr(dbfle.a,253,8) /* resource class               */
grbd_gen = substr(dbfle.a,262,3)   /* generic - YES/NO             */
grbd_uacc = substr(dbfle.a,337,8)  /* uacc - ALTER/CONTROL/UPDATE/ */
                                   /* READ/EXECUTE/NONE            */
grdb_warn = substr(dbfle.a,660,3)  /* warning - YES/NO             */
If grbd_warn = "YES" then do
/* grbd_warn = "YES" |,
   rwarn = 0 then do*/
  rwarn = rwarn + 1
  rwarntab.rwarn = UCN_0500 grbd_rescl grbd_gen grbd_warn
  end
 
/* Bypass the following resource classes*/
If grbd_rescl = 'DIGTCERT' |,
   grbd_rescl = 'NODES' then ,
  return
/* Bypass the above resource classes */
 
If grbd_uacc <> "NONE" &,
   pos("TRUST",grbd_uacc) = 0 then do
/*If (grbd_uacc <> "NONE" &,
   pos("TRUST",grbd_uacc) = 0) |,
   rwarn = 0 then do*/
  ruacc = ruacc + 1
  ruacctab.ruacc = UCN_0500 grbd_rescl grbd_gen grbd_uacc
  end
return
 
 
process_queued_pdi:
Say pgmname right(queued(),4) "records written for" pdi"."
do xx = 1 to queued()
  parse pull ac
  "LMPUT DATAID("pdidd") MODE(INVAR) DATALOC(ac)",
    "DATALEN("length(ac)") MEMBER("pdi")"
  end
"LMMADD DATAID("pdidd") MEMBER("pdi")"
Say PGMNAME "LMMADD_PDIDD_RC =" return_code PDI ZERRSM
if return_code = 4 then do
  "LMMREP DATAID("pdidd") MEMBER("pdi")"
  if return_code <> 0 then,
    Say PGMNAME "LMMREP_PDIDD_RC =" return_code PDI ZERRSM
  end
return_code = 0
return
 
 
NoValue:
Failure:
Syntax:
Say pgmname "REXX error" rc "in line" sigl":" strip(ERRORTEXT(rc))
Say SOURCELINE(sigl)
SIGNAL ERR_EXIT
 
 
Error:
return_code = RC
if RC > 4 & RC <> 8 then do
  Say pgmname "LASTCC =" RC strip(zerrlm)
  Say pgmname "REXX error" rc "in line" sigl":" ERRORTEXT(rc)
  Say SOURCELINE(sigl)
  end
if return_code > maxcc then,
  maxcc = return_code
if maxcc = 4 then,
  maxcc = 0
return
 
 
