/* REXX */
/*                                       */
/* AUTHOR: Charles Fenton                */
/*                                       */
/*trace ?r*/
Signal On NoValue
Call On Error
Signal On Failure
Signal On Syntax
Parse source opsys . exec_name .
 
/*********************************************************************/
/* This script collect OMVS information on users and groups, then    */
/* evaluates SYS1.UADS dataset.                                      */
/*********************************************************************/
/* Change summary:                                                   */
/* 11/03/2008 CL Fenton Initial creation of script generate and      */
/*            obtain OMVS information from ACPs and generate         */
/*            finding details.                                       */
/* 02/26/2010 CL Fenton Chgd format of output mgs stats.             */
/* 03/11/2011 CL Fenton Update in obtain addition information.       */
/*            And changed data set from po to ps.                    */
/* 08/16/2013 CL Fenton Chg to put PROFILE VARSTORAGE(HIGH)          */
/*            within script, STS-003055.                             */
/* 09/24/2019 CL Fenton Chg commands issued and process for ACF2,    */
/*            STS-023242.                                            */
/* 01/22/2026 CL Fenton Added error processing with return_code and  */
/*            automation for PDI ZTSO0020 for ACF2-ES-000350,        */
/*            RACF-TS-000020, and TSS0-TS-000020, SCTASKU0518035.    */
/*                                                                   */
/*                                                                   */
/*                                                                   */
/*********************************************************************/
pgmname = "CACC0008 01/22/26"
conslist = "OFF"           /* default is off                         */
comlist  = "OFF"           /* default is off                         */
symlist  = "OFF"           /* default is off                         */
termmsgs = "OFF"           /* default is off                         */
trace =    "OFF"           /* trace actions and errors               */
lminit_pdidd        = "N/A"
lminit_dialog       = "N/A"
lminit_ussdd        = "N/A"
lmopen_pdidd        = "N/A"
lmopen_dialog       = "N/A"
lmmfind_dialog      = "N/A"
lmopen_ussdd        = "N/A"
lminit_uadsdd       = "N/A"
lmopen_uadsdd       = "N/A"
lmmlist_uadsdd      = "N/A"
lmmlist_free_uadsdd = "N/A"
lmclose_uadsdd      = "N/A"
lmfree_uadsdd       = "N/A"
acprc               = "N/A"
edit_ussrpt1        = "N/A"
edit_ussrpt2        = "N/A"
lmclose_pdidd       = "N/A"
lmclose_dialog      = "N/A"
lmclose_ussdd       = "N/A"
lmfree_pdidd        = "N/A"
lmfree_dialog       = "N/A"
lmfree_ussdd        = "N/A"
Numeric digits 10                 /* default of 9 not enough         */
return_code = 0
maxcc = 0
MEMBER   = "ZUSS0046"
"profile varstorage(high)"
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
 
Address ISPEXEC
"CONTROL NONDISPL ENTER"
"CONTROL ERRORS RETURN"
zispfrc = 0
"VPUT (ZISPFRC) SHARED"
"VPUT (CONSLIST COMLIST SYMLIST TERMMSGS)"
If CONSLIST = "ON" | COMLIST = "ON" | SYMLIST = "ON" | TRACE = "ON",
  then Trace ?r
"ISPEXEC SELECT CMD(CACC1000 ACP)"
"VGET (ACPNAME ACPVERS)"
return_code = 0
"lminit dataid(pdidd) ddname(pdidd)"
lminit_pdidd = return_code
return_code = 0
"lminit dataid(dialog) ddname(dialog)"
lminit_dialog = return_code
return_code = 0
"lminit dataid(ussdd) ddname(ussrpt)"
lminit_ussdd = return_code
return_code = 0
"lmopen dataid("pdidd") option(output)"
lmopen_pdidd = return_code
return_code = 0
"lmopen dataid("dialog")"
lmopen_dialog = return_code
"VPUT (PDIDD DIALOG)"
return_code = 0
"lmopen dataid("ussdd") option(output)"
lmopen_ussdd = return_code
/*********************************************************************/
/* Generate security commands for OMVS users.                        */
/*********************************************************************/
return_code = 0
x = outtrap("out.")
if ACPNAME = "RACF" then do
  address TSO "LU * OMVS"
  address TSO "LG * NORACF OMVS"
  MACRO = "CARM0100"
  end
if ACPNAME = "TSS" then do
  address TSO "TSS LIST(ACIDS)DATA(BASIC)SEGMENT(OMVS)"
  MACRO = "CATM0100"
  end
if ACPNAME = "ACF2" then do
  queue "LIST LIKE(-) SECTION(RESTRICTIONS) PROFILE(OMVS)"
  queue "SET PROFILE(GROUP) DIVISION(OMVS)"
  queue "LIST LIKE(-)"
  queue "QUIT"
  queue ""
  address TSO "ACF"
  MACRO = "CAAM0100"
  end
x = outtrap("OFF")
acprc = return_code
address TSO "DELSTACK"
address TSO "DELSTACK"
Say pgmname "Record count is" out.0"."
do x = 1 to out.0
  ac = " "out.x
  "LMPUT DATAID("ussdd") MODE(INVAR) DATALOC(ac)",
    "DATALEN("length(ac)")"
  end
return_code = 0
"lmclose dataid("ussdd")"
lmclose_ussdd = return_code
Say pgmname "Processing data for script" MACRO"."
return_code = 0
"EDIT DATAID("ussdd") MACRO("MACRO")"
edit_ussrpt1 = return_code
Say pgmname "Processing data for script CACM0100."
return_code = 0
"EDIT DATAID("ussdd") MACRO(CACM0100)"
edit_ussrpt2 = return_code
 
Call Process_UADS
If queued() <> 0 then Call Process_PDI
 
return_code = 0
"lmclose dataid("pdidd")"
lmclose_pdidd = return_code
return_code = 0
"lmclose dataid("dialog")"
lmclose_dialog = return_code
return_code = 0
"lmfree dataid("pdidd")"
lmfree_pdidd = return_code
return_code = 0
"lmfree dataid("dialog")"
lmfree_dialog = return_code
return_code = 0
"lmfree dataid("ussdd")"
lmfree_ussdd = return_code
/*******************************************/
/* 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
 
If TERMMSGS = "ON" then do
  Say "==============================================================="
  Say pgmname "LMINIT_PDIDD                      "lminit_pdidd
  Say pgmname "LMINIT_DIALOG                     "lminit_dialog
  Say pgmname "LMINIT_USSDD                      "lminit_ussdd
  Say pgmname "LMOPEN_PDIDD                      "lmopen_pdidd
  Say pgmname "LMOPEN_DIALOG                     "lmopen_dialog
  Say pgmname "LMMFIND_DIALOG EMERAUDIT          "lmmfind_dialog
  Say pgmname "LMOPEN_USSDD                      "lmopen_ussdd
  Say pgmname "ACP_RC                            "acprc
  Say pgmname "EDIT_USSRPT "MACRO"              "edit_ussrpt1
  Say pgmname "EDIT_USSRPT CACM0100              "edit_ussrpt2
  Say pgmname "LMCLOSE_PDIDD                     "lmclose_pdidd
  Say pgmname "LMCLOSE_DIALOG                    "lmclose_dialog
  Say pgmname "LMCLOSE_USSDD                     "lmclose_ussdd
  Say pgmname "LMFREE_PDIDD                      "lmfree_pdidd
  Say pgmname "LMFREE_DIALOG                     "lmfree_dialog
  Say pgmname "LMFREE_USSDD                      "lmfree_ussdd
  Say "==============================================================="
  Say pgmname "LMINIT_UADSDD                     "lminit_uadsdd
  Say pgmname "LMOPEN_UADSDD                     "lmopen_uadsdd
  Say pgmname "LMMLIST_UADSDD                    "lmmlist_uadsdd
  Say pgmname "LMMLIST_FREE_UADSDD               "lmmlist_free_uadsdd
  Say pgmname "LMCLOSE_UADSDD                    "lmclose_uadsdd
  Say pgmname "LMFREE_UADSDD                     "lmfree_uadsdd
  Say "==============================================================="
  end
Exit 0
 
 
/*********************************************************************/
/*  Start of sub-routines                                            */
/*********************************************************************/
 
 
Process_UADS:
emerusers = ""
return_code = 0
"lmmfind dataid("dialog") member(emeraudt)"
lmmfind_dialog = return_code
do until return_code > 0
  "lmget dataid("dialog") mode(invar) dataloc(data) datalen(lrecl)",
  "maxlen(80)"
  if return_code = 0 then,
    emerusers = emerusers left(data,8)
  end /* until return_code > 0 */
emerusers = strip(emerusers)
return_code = 0
"LMINIT DATAID(UADSDD) DATASET('SYS1.UADS')"
lminit_uadsdd = return_code
return_code = 0
"LMOPEN DATAID("uadsdd")"
lmopen_uadsdd = return_code
return_code = 0
uadsuser. = ""
uadsuser.0 = 0
pdi = "ZTSO0020"
a = 0
Do until return_code <> 0
  "LMMLIST DATAID("uadsdd") OPTION(LIST) MEMBER(MBRUADS)"
  If return_code = 0 then do
    uadsuser = left(mbruads,length(mbruads) - 1)
/*  Say pgmname mbruads uadsuser*/
    x = outtrap("out.",1)
    if ACPNAME = "ACF2" then do
      queue "LIST" uadsuser
      queue "QUIT"
      queue ""
      address TSO "ACF"
      end
    if ACPNAME = "RACF" then do
      address TSO "LU" uadsuser
      end
    if ACPNAME = "TSS" then do
      Address TSO "TSS LIST("uadsuser")DATA(BASIC)"
      end
/*  Say pgmname uadsuser return_code "CNT" out.0*/
    if return_code <> 0 then do
      a = a + 1
      uadsuser.0 = a
      uadsuser.a = uadsuser "is not defined to" ACPNAME
      end
    else,
      if wordpos(emerusers,uadsuser) = 0 then do
        a = a + 1
        uadsuser.0 = a
        uadsuser.a = uadsuser "is not identified in EMERAUDT"
        end
    do x = 1 to out.0
      Say pgmname x "=" out.x
      end
    return_code = 0
    x = outtrap("OFF")
    end
  end
lmmlist_uadsdd = return_code
/*Say pgmname "UADSUSER CNT =" uadsuser.0*/
Address TSO "delstack"
If uadsuser.0 > 0 then do
  queue "The following UADS userid(s) are identified with errors."
  queue " "
  do x = 1 to uadsuser.0
    Say pgmname x uadsuser.x
    queue "    " uadsuser.x
    end
  end
Else do
  push "Not a Finding"
  end
return_code = 0
"LMMLIST DATAID("uadsdd") OPTION(FREE)"
lmmlist_free_uadsdd = return_code
return_code = 0
"LMCLOSE DATAID("uadsdd")"
lmclose_uadsdd = return_code
return_code = 0
"LMFREE DATAID("uadsdd")"
lmfree_uadsdd = return_code
 
 
Return
 
 
Process_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
return_code = 0
"LMMADD DATAID("pdidd") MEMBER("pdi")"
if return_code = 4 then do
  return_code = 0
  "LMMREP DATAID("pdidd") MEMBER("pdi")"
  if return_code <> 0 then,
    Say pgmname "LMMREP_PDIDD =" return_code PDI ZERRSM
  end
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
return
 
 
