/*REXX*/ /* */ /* AUTHOR: Charles Fenton */ /* */ /**************************************************************/ /* ITEM: CNTL(CACC0010) */ /* FUNCTION: REXX for OS/390 UNIX System Services */ /* data collection */ /* */ /* NOTES: - This member contains UNIX file names. */ /* - It MUST stay in mixed case. */ /* - It MUST NOT be numbered. */ /*********************************************************************/ /* Change summary: */ /* 07/07/2000 DCM Start */ /* 11/19/2009 CL Fenton Changes to allow for use of BPXWUNIX. */ /* 04/24/2012 CL Fenton initial creation of script copied from */ /* USSICOL1, CSD-AR003400262. */ /* 05/21/2015 CL Fenton Changed includes test for CSFTP, CSTCP, */ /* and WAS to stream line process, STS-008182. */ /* 08/11/2016 CL Fenton Cleaned up several unneccessary entries. */ /* 05/04/2018 CL Fenton Changed process to work from users HOME */ /* directory. If blank will use /tmp/(username) as */ /* directory, STS-019498. */ /* 02/31/2019 CL Fenton Changes to initialize CWD variable, */ /* STS-021618. */ /* 09/25/2019 CL Fenton Changes to check the value of CWD and the */ /* RETVAL from the getcwd commands to determine if the */ /* /tmp directory is to be used, STS-023237 and */ /* STS-023242. */ /* 11/08/2019 CL Fenton Added automation for IUTN0010 and IUTN0020, */ /* STS-023415 and STS-023417. */ /* 03/29/2021 CL Fenton Added evaluation for sntpd PDI ZUSS0037 for */ /* ACF2-OS-000150, RACF-OS-000190, and TSS0-OS-000280, */ /* STS-026250. */ /* */ /* */ /* */ /* */ /*********************************************************************/ /* Setup variables for copying report files */ /* */ /* PARSE UPPER ARG VDSNNODE . */ /*********************************************************************/ PGMNAME = 'CACC0010 03/29/21' TERMMSGS = 'OFF' COMLIST = 'OFF' CONSLIST = 'OFF' SYMLIST = 'OFF' TERMPRO = 'OFF' lc = 'abcdefghijklmnopqrstuvwxyz' uc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' username = translate(userid(),lc,uc) Arg OPTION OPTION = translate(OPTION,'=;','()') interpret OPTION if TRACE = 'ON' then do TERMMSGS = ON COMLIST = ON CONSLIST = ON SYMLIST = ON TERMPRO = ON end Address ISPEXEC "CONTROL NONDISPL ENTER" "CONTROL ERRORS RETURN" "VPUT (CONSLIST COMLIST SYMLIST TERMPRO TERMMSGS)" If CONSLIST = ON | COMLIST = ON | SYMLIST = ON | TRACE = ON , then Trace r "SELECT CMD(CACC1000 ACP)" Address TSO pdi = '' cwd = '' cwdrc = 0 Numeric digits 10 /* dflt of 9 not enough */ Arg OPTION OPTION = translate(OPTION,'=;','()') interpret OPTION call syscalls 'ON' say PGMNAME "syscalls" rc address syscall "getlogin lid" say PGMNAME "getlogin" lid rc RETVAL ERRNO ERRNOJR address syscall "getcwd cwd" say PGMNAME "getcwd" cwd rc RETVAL ERRNO ERRNOJR if retval = -1 or cwd = "/" then do say PGMNAME "Either" lid "has a HOME of Root (/) or the", "/u/"username "directory is not defined to Unix." set cwdrc = -1 end address syscall "getuid" say PGMNAME "getuid" rc RETVAL ERRNO ERRNOJR uid = RETVAL address syscall "getgid" say PGMNAME "getgid" rc RETVAL ERRNO ERRNOJR gid = RETVAL address syscall "geteuid" say PGMNAME "geteuid" rc RETVAL ERRNO ERRNOJR euid = RETVAL address syscall "getegid" say PGMNAME "getegid" rc RETVAL ERRNO ERRNOJR egid = RETVAL uidsu = "" gidsu = "" if uid <> 0 then do address syscall "setuid 0" say PGMNAME "setuid" rc RETVAL ERRNO ERRNOJR if retval <> -1 then do address syscall "getuid" say PGMNAME "getuid" rc RETVAL ERRNO ERRNOJR uidsu = RETVAL address syscall "getgid" say PGMNAME "getgid" rc RETVAL ERRNO ERRNOJR gidsu = RETVAL cwdsu = "" address syscall "getcwd cwdsu" say PGMNAME "getcwd" cwdsu rc RETVAL ERRNO ERRNOJR if retval = -1 or cwdsu = "/" then do say PGMNAME "Either" lid "has a HOME of Root (/) or the", "u/"username "directory is not defined to Unix." set cwdrc = -1 end end end X = LISTDSI(USSCMDS FILE) VDSNFULL = SYSDSNAME Address ISPEXEC "lminit dataid(dialog) ddname(dialog)" lminit_dialog = RC "lminit dataid(pdidd) ddname(pdidd)" lminit_pdidd = RC "lmopen dataid("dialog")" lmopen_dialog = RC "lmopen dataid("pdidd") option(output)" lmopen_pdidd = RC /*VHFSFULL = "/tmp/fso_srrmvs/usscmds_rpt/" address syscall "lstat (VHFSFULL) dir." say pgmname "lstat" dir.0 rc RETVAL ERRNO ERRNOJR say pgmname "lstat st_uid" dir.st_uid say pgmname "lstat st_type" dir.st_type if uid <> 0 & uidsu <> 0 & uid <> dir.st_uid then , VHFSPART = cwd else , VHFSPART = "/tmp"*/. if cwdrc = 0 then, VHFSPART = cwd else , VHFSPART = "/tmp/"username address syscall "opendir "VHFSPART say pgmname "opendir" rc RETVAL ERRNO ERRNOJR if RETVAL = -1 then , address syscall "mkdir (VHFSPART) 0750" address syscall "closedir "RETVAL say pgmname "closedir" rc RETVAL ERRNO ERRNOJR address syscall "lstat (VHFSPART) dir." /*say pgmname "lstat" dir.0 rc RETVAL ERRNO ERRNOJR say pgmname "lstat st_uid" dir.st_uid say pgmname "lstat st_type" dir.st_type*/ VHFSFULL = VHFSPART"/fso_srrmvs/usscmds_rpt" say pgmname "Home directory set to" VHFSPART"." say pgmname "Work information can be found in directory" VHFSFULL"." urc = BPXWUNIX('df -P',,df.,'DD:SYSERR') AUTOMNT = "NONE" do x = 1 to df.0 /*say pgmname df.x*/ if substr(df.x,1,1) = "*" then , AUTOMNT = word(df.x,6) end /* */ /* Allocate HFS file; copy script to it */ /* */ Address TSO cmd=VHFSPART'/fso_srrmvs_usscmds_ksh' /*"OCOPY INDD(MVSENV) OUTDD(STDENV) TEXT CONVERT((BPXFX111))"*/ env.0 = 0 x = outtrap("out.") listalc status x = outtrap(off) do x = 1 to out.0 if pos("MVSENV",out.x) <> 0 then do y = x - 1 DSN="'"strip(out.y)"'" leave end end if SYSDSN(DSN) = "OK" then , "execio * diskr MVSENV (FINIS STEM env." x = env.0 + 1 env.x = "HOME="VHFSPART say pgmname "HOME="VHFSPART env.0 = x x = env.0 + 1 env.x = "AUTOMNT="AUTOMNT say pgmname "AUTOMNT="AUTOMNT env.0 = x typeruns = "CSFTP CSTCP WAS" y = "Y" n = "N" do until typeruns = "" parse var typeruns TYPERUN typeruns TYPERUN = left(TYPERUN,8) rectype = "0" Call collect_rec OPTION = strip(TYPERUN)||'='||ind x = env.0 + 1 env.x = OPTION say pgmname OPTION env.0 = x interpret OPTION end /*say pgmname "CSFTP:"csftp "CSTCP:"cstcp "WAS:"was*/ DO x = 1 to env.0 env.x = strip(env.x) /*say pgmname 'env' x env.x*/ end /* */ "ALLOCATE FILE(HFS01) PATH('"VHFSPART"/fso_srrmvs_usscmds_ksh') ", "PATHDISP(KEEP,DELETE) ", "PATHOPTS(OWRONLY,OCREAT) ", "PATHMODE(SIRWXU)" say pgmname "ALLOCATE HFS01" rc "OCOPY INDD(MVS01) OUTDD(HFS01) TEXT CONVERT((BPXFX111))" say pgmname "OCOPY MVS01 to HFS01" rc "FREE FILE(HFS01)" /* */ /* Allocate Shell STDIN, STDOUT; execute script; free files */ /* */ "ALLOCATE FILE(STDIN) PATH('"VHFSPART"/fso_srrmvs_usscmds_ksh') ", "PATHDISP(DELETE,DELETE) ", "PATHOPTS(ORDONLY)" urc = BPXWUNIX('sh -L' cmd,,'DD:SYSMSG','DD:SYSERR',env.) say pgmname "BPXWUNIX" rc urc "FREE FILE(STDIN)" /* */ /* Copy HFS report files to PDS */ /* */ VRPT = "eautom" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" VRPT = "einetd" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" call process_inetd VRPT = "eprof" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" VRPT = "erc" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" VRPT = "eserv" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" VRPT = "estepll" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" VRPT = "owdir" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" VRPT = "sdperm" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" pdi = "zuss0034" call process_permission_pdi VRPT = "sfperm" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" pdi = "zuss0035" call process_permission_pdi if CSTCP = "Y" then do VRPT = "itcp0040" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" call process_permission_pdi end VRPT = "iutn0030" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" VRPT = "iutn0040" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" call process_permission_pdi if CSFTP = "Y" then do VRPT = "iftp0050" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" /*call process_permission_pdi*/ VRPT = "iftp0070" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" call process_permission_pdi end VRPT = "islg0030" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" call process_permission_pdi VRPT = "zuss0037" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" call process_permission_pdi /* */ /* Allocate HFS file; copy script to it */ /* */ if WAS = "N" then signal bypass_was "ALLOCATE FILE(HFS01) PATH('"VHFSPART"/fso_srrmvs_usscmds_ksh') ", "PATHDISP(KEEP,DELETE) ", "PATHOPTS(OWRONLY,OCREAT) ", "PATHMODE(SIRWXU)" "OCOPY INDD(MVS02) OUTDD(HFS01) TEXT CONVERT((BPXFX111))" "FREE FILE(HFS01)" /* */ /* Allocate Shell STDIN, STDOUT; execute script; free files */ /* */ "ALLOCATE FILE(STDIN) PATH('"VHFSPART"/fso_srrmvs_usscmds_ksh') ", "PATHDISP(DELETE,DELETE) ", "PATHOPTS(ORDONLY)" urc = BPXWUNIX('sh -L' cmd,,'DD:SYSMSG','DD:SYSERR',env.) say pgmname "BPXWUNIX" rc urc "FREE FILE(STDIN)" /* */ /* Copy HFS report files to PDS */ /* */ VRPT = "ihshfsob" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" VRPT = "washfsob" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" VRPT = "ahttpd" "OGET '"VHFSFULL'/'VRPT"' '"VDSNFULL"("VRPT")' TEXT CONVERT((BPXFX111))" bypass_was: call syscalls 'OFF' Address ISPEXEC "lmclose dataid("dialog")" lmclose_dialog = RC "lmclose dataid("pdidd")" lmclose_pdidd = RC "lmfree dataid("dialog")" lmfree_dialog = RC "lmfree dataid("pdidd")" lmfree_pdidd = RC /* */ If TERMMSGS = ON then do say say '===============================================================' say PGMNAME 'LMINIT_DIALOG ' lminit_dialog say PGMNAME 'LMINIT_PDIDD ' lminit_pdidd say PGMNAME 'LMOPEN_DIALOG ' lmopen_dialog say PGMNAME 'LMOPEN_PDIDD ' lmopen_pdidd say PGMNAME 'LMCLOSE_DIALOG ' lmclose_dialog say PGMNAME 'LMCLOSE_PDIDD ' lmclose_pdidd say PGMNAME 'LMFREE_DIALOG ' lmfree_dialog say PGMNAME 'LMFREE_PDIDD ' lmfree_pdidd say '===============================================================' end Exit 0 /*********************************************************************/ /* Start of sub-routines */ /*********************************************************************/ process_permission_pdi: Address ISPEXEC if pdi = "" then pdi = VRPT upper pdi pb = 0 uab = 0 f1 = "Permission bits and user audit bits is (are) inappropriate:" f2 = "Permission bits allow inappropriate access." f3 = "User audit bits provide inadequate logging." address tso "alloc fi(input) da('"VDSNFULL"("VRPT")') shr reuse" address tso "execio * diskr input (finis stem out." do a = 1 to out.0 parse var out.a ind 2 sp 5 data /*say pgmname "ind="ind "sp="sp "data="data*/ if ind = "" then iterate if ind = "0" then iterate if ind = "1" then pb = pb + 1 if ind = "2" then uab = uab + 1 if ind = "3" then do pb = pb + 1 uab = uab + 1 end end say PGMNAME 'Processing PDI' pdi'. pb='pb 'uab='uab Address TSO "newstack" if pb = 0 & uab = 0 then queue 'Not a Finding' if pb > 0 | uab > 0 then do queue f1 queue " " end if pb > 0 & uab > 0 then do nr = 1 lp = ") " end else do nr = "" lp = "" end if pb > 0 then do queue nr""lp""f2 queue " " if nr > 0 then nr = nr + 1 do a = 1 to out.0 parse var out.a ind 2 sp 5 data if ind = "1" | ind = "3" then , queue " "data end queue " " end if uab > 0 then do queue nr""lp""f3 queue " " do a = 1 to out.0 parse var out.a ind 2 sp 5 data if ind = "2" | ind = "3" then , queue " "data end queue " " end say pgmname right(queued(),4) 'records written for' pdi'.' do x = 1 to queued() parse pull ac "LMPUT DATAID("pdidd") MODE(INVAR) DATALOC(ac)", "DATALEN("length(ac)") MEMBER("pdi")" end "LMMADD DATAID("pdidd") MEMBER("pdi")" if RC = 4 then do "LMMREP DATAID("pdidd") MEMBER("pdi")" if RC <> 0 then, say PGMNAME 'LMMREP_PDIDD =' RC PDI ZERRSM end Address TSO "delstack" pdi = "" Address TSO "free fi(input)" return process_inetd: inetd_data = "" Address ISPEXEC address tso "alloc fi(input) da('"VDSNFULL"("VRPT")') shr reuse" address tso "execio * diskr input (finis stem out." do a = 1 to out.0 parse var out.a out.a "#" . if out.a = "" then iterate if word(out.a,1) = "otelnet" then do inetd_data = out.a leave end end pdi = "IUTN0010" say PGMNAME 'Processing PDI' pdi'.' Address TSO "newstack" if inetd_data = "" then, queue "Not Applicable" else do if word(inetd_data,5) = "OMVS" |, word(inetd_data,5) = "OMVSKERN" then, queue "Not a Finding" else do queue "The startup user account for the z/OS UNIX Telnet Server", "does not specify OMVS or OMVSKERN." queue " " queue " "word(inetd_data,5) "is specified." end end say pgmname right(queued(),4) 'records written for' pdi'.' do x = 1 to queued() parse pull ac "LMPUT DATAID("pdidd") MODE(INVAR) DATALOC(ac)", "DATALEN("length(ac)") MEMBER("pdi")" end "LMMADD DATAID("pdidd") MEMBER("pdi")" if RC = 4 then do "LMMREP DATAID("pdidd") MEMBER("pdi")" if RC <> 0 then, say PGMNAME 'LMMREP_PDIDD =' RC PDI ZERRSM end Address TSO "delstack" pdi = "IUTN0020" say PGMNAME 'Processing PDI' pdi'.' Address TSO "newstack" if inetd_data = "" then, queue "Not Applicable" else do login = "" timeout = "" x = wordindex(inetd_data,7) parse var inetd_data . =(x) inetd_parm parse var inetd_parm . "-D" login . parse var inetd_parm . "-c" timeout . if pos("-h",inetd_parm) = 0 &, login = "login" &, timeout <= 900 then, queue "Not a Finding" else do queue "Startup parameters for the z/OS UNIX Telnet Server are", "improperly specified." queue " " queue " "inetd_parm end end say pgmname right(queued(),4) 'records written for' pdi'.' do x = 1 to queued() parse pull ac "LMPUT DATAID("pdidd") MODE(INVAR) DATALOC(ac)", "DATALEN("length(ac)") MEMBER("pdi")" end "LMMADD DATAID("pdidd") MEMBER("pdi")" if RC = 4 then do "LMMREP DATAID("pdidd") MEMBER("pdi")" if RC <> 0 then, say PGMNAME 'LMMREP_PDIDD =' RC PDI ZERRSM end Address TSO "delstack" pdi = "" Address TSO "free fi(input)" return collect_rec: Address ISPEXEC "lmmfind dataid("dialog") member(products)" lmmfind_dialog = RC TYPERUN = left(TYPERUN,8) RC = 0 recs = do until RC>0 "lmget dataid("dialog") mode(invar) dataloc(data) datalen(lrecl)", "maxlen(80)" if RC = 0 & , pos(TYPERUN' 'rectype,data) = 1 then do parse var data . "0" ind ind = strip(ind) return 0 end /* if RC = 0 & */ end /* until RC>0 */ return 0