PROC 0 DISPLAY DATASET() PREFIX(&SYSUID) Q() L() E() + IGNORE() TERSE CONTROL MAIN ASIS /**************************************************************/ /* Note -- have reworked code to add the following options */ /* Q(), E(), L(), IGNORE(), and TERSE. D.McRitchie */ /* allowing anyone to use this clist in a normal fashion. */ /* Formatted document online ===> TSO CLIST LISTRP HELP */ /* Source for documentation -- IS03.SHARE.TEXT(LISTRP) */ /**************************************************************/ /* 5740-XXH COPYRIGHT IBM CORP 1984 */ /* LICENSED MATERIAL - PROGRAM PROPERTY OF IBM */ /* REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083 */ /* RESTRICTED MATERIALS OF IBM */ /* */ /* LIST RACF PROTECTION - %LISTRP */ /* */ /* THE PURPOSE OF THIS CLIST IS TO DEMONSTRATE A METHOD */ /* OF COMBINING CATALOG SUPPORT (IDCAMS) AND THE RACF */ /* SEARCH COMMAND TO REPORT ON WHAT DATA SET(S) ARE */ /* PROTECTED BY WHAT RACF GENERIC AND DISCRETE PROFILES. */ /* */ /* THIS CLIST INVOKES THE RACF SEARCH COMMAND WITH THE */ /* CLIST OPTION. IF YOU HAVE AN 'USERID.EXEC.RACF.CLIST' */ /* DATA SET, IT WILL BE DELETED BY THIS CLIST. YOU MUST */ /* HAVE THE RACF SPECIAL OR AUDITOR ATTRIBUTES WHEN USING */ /* THE PREFIX OPERAND AND THE PREFIX IS NOT YOUR RACF */ /* USERID. */ /* */ /* CONSIDER RUNNING THIS CLIST IN BATCH UNDER THE TMP */ /* WHEN LARGE NUMBERS OF PROFILES AND/OR DATASET NAMES OR */ /* CATALOG ENTRIES ARE INVOLVED. */ /* */ /* THIS CLIST IS AN EXAMPLE ONLY AND IS NOT SUPPORTED IN */ /* ANY WAY. IT IS PROBABLE THAT MODIFICATIONS TO THIS */ /* CLIST WILL BE NECESSARY BEFORE IT COULD BE CONSIDERED */ /* USEFUL IN ANY PARTICULAR INSTALLATION. */ /* */ /* AS WRITTEN, THIS CLIST PROVIDES THE FOLLOWING FUNCTION. */ /* (1) IF A PREFIX IS SPECIFIED VIA THE PREFIX OPERAND, */ /* THEN THE PREFIX IS USED TO QUALIFY THE RACF PROFILES */ /* AND DATASET NAMES FOR THE PROFILE SEARCH AND THE */ /* CATALOG SEARCH. */ /* (2) IF A DATA SET NAME IS SPECIFIED VIA THE DATASET */ /* OPERAND, THEN IT REPORTS WHICH OF THE PROFILES */ /* UNDER 'PREFIX' PROTECTS THE DATA SET. */ /* (3) IF YOU SPECIFY NO OPERANDS, THEN ALL YOUR CATALOGED */ /* DATA SET ARE MATCHED TO THE PROFILES THAT COVER */ /* THEM. */ /* */ /* TO USE THIS CLIST YOUR USERID MUST MATCH THE HIGH LEVEL */ /* INDEX OF THE DATA SET(S) OR YOU MUST HAVE THE RACF */ /* 'SPECIAL' ATTRIBUTE. */ /**************************************************************/ /* This clist has been modified at "The REXX Macros Toolbox" to make */ /* it possible for anyone to check datasets. Examples: */ /* ===> TSO LISTRF */ /* ===> TSO LISTRF PREFIX(userid) */ /* ===> TSO LISTRF L(userid.LIBR) */ /* ===> TSO LISTRF Q(fully.qualified.dsname) */ /* ===> TSO LISTRF L(userid.LIBR) DISPLAY */ /* ===> TSO LISTRF E(userid.*.LIBR) DISPLAY */ /**************************************************************/ /* */ /* THE SYNTAX AND OPERANDS OF THE CLIST ARE AS FOLLOWS: */ /* */ /* SYNTAX - */ /* LISTRP DATASET(DATASET-NAME) PREFIX(PREFIX) DISPLAY */ /* */ /* REQUIRED - NONE */ /* */ /* OPERANDS - */ /* 'Q()' - FULLY QUALIFIED DATASET NAME W/O QUOTES */ /* DO NOT USE DATASET() OR PREFIX() IF USING. */ /* (OPTION ADDED BY FRUSTRATED FDM user) */ /* */ /* 'L()' - LISTCAT LEVEL() DATASET NAME W/O QUOTES */ /* DO NOT USE DATASET() OR PREFIX() IF USING. */ /* (OPTION ADDED BY FRUSTRATED FDM user) */ /* */ /* 'E()' - LISTCAT ENT() DATASET NAME W/O QUOTES */ /* DO NOT USE DATASET() OR PREFIX() IF USING. */ /* E(is03.*.cntl) e(is03.share.*) */ /* (OPTION ADDED BY FRUSTRATED FDM user) */ /* */ /* 'DATASET()' - SPECIFIES A DATA SET NAME FOR WHICH YOU */ /* WANT TO FIND THE RELATED RACF PROFILE. */ /* */ /* 'PREFIX()' - SPECIFIES A HIGH-LEVEL QUALIFIER FOR WHICH */ /* YOU WANT TO FIND ALL THE DATASETS AND THE */ /* RELATED RACF PROFILES. IF THE DATASET */ /* OPERAND IS ALSO SPECIFIED, THEN THE PREFIX */ /* IS USED TO QUALIFY THE DATASET NAME. */ /* */ /* 'DISPLAY' - REQUESTS THAT PROFILE INFORMATION BE */ /* DISPLAYED. THE DEFAULT IS NO DISPLAY. */ /**************************************************************/ SET SAVED = &STR(&SYSDATE. &SYSTIME.) ATTN DO WRITE ATTENTION NOTED. GOTO REALEND END SET B44 = &STR( ) SET LENGLVL = 0 SET LENGENT = 0 SET RACFY = 0 /* dataset is racf protected */ SET RACFN = 0 /* dataset not racf protected */ SET RACFP = 0 /* possibly not racf protected */ SET RACFU = 0 /* UNMATCHED --DONT CARE IF LVL*/ SET PMATCHT = 0 /* TOTAL CUMULATIVE MATCHES ON PROFILES SET LISTCR = 0 /* listcat records */ SET LISTCP = 0 /* listcat records printed */ SET PROFP = 0 /* profile records printed */ SET CATWK = &STR(YES) SET SINGLELD = &STR() /* The following code has been inserted by FDM /* The above code and the word ELSE below was inserted by FDM IF &LENGTH(&STR(&E.)) ^= 0 THEN + DO SET LENGENT = &LENGTH(&STR(&E.)) SET LENGLVL = &LENGTH(&STR(&E.)) SET DATASET= &STR(&E.) SET I = &SYSINDEX(.,&DATASET. ) IF &I. = 0 THEN + SET PREFIX = &STR(&DATASET.) ELSE DO SET I = &I. - 1 SET PREFIX = &SUBSTR(1:&I,&STR(&DATASET.)) END SET USED = LISTRP E(&STR(&E.)) SET USED2 = LISTC ENT('&STR(&DATASET.)') END /* The above code and the word ELSE below was inserted by FDM ELSE IF &LENGTH(&STR(&L.)) ^= 0 THEN + DO SET LENGLVL = &LENGTH(&STR(&L.)) SET DATASET= &STR(&L.) /** removed the following by resetting prefix**/ SET I = &SYSINDEX(.,&DATASET. ) IF &I. = 0 THEN + SET PREFIX = &STR(&DATASET.) ELSE DO SET I = &I. - 1 SET PREFIX = &SUBSTR(1:&I,&STR(&DATASET.)) END /** removed the above*/ SET PREFIX = &STR(&DATASET.) SET USED = LISTRP L(&STR(&PREFIX.)) SET USED2 = LISTC LEVEL(&STR(&DATASET.)) END /* The following code has been inserted by FDM ELSE IF &LENGTH(&STR(&Q)) ^= 0 THEN + DO SET USED = LISTRP Q(&STR(&Q.)) SET DATASET= &STR(&Q.) SET CATWK = &STR(NO) SET I = &SYSINDEX(*,&DATASET. ) IF &EVAL(&I.) ^= &EVAL(0) THEN DO WRITE THE USE OF ASTERISK(*) IS NOT PERMITTED + -- LISTRP L(&STR(&Q.)) EXIT CODE(8) END SET I = &SYSINDEX(.,&DATASET. ) SET I = &I. - 1 SET PREFIX = &SUBSTR(1:&I.,&STR(&DATASET.)) SET USED2 = LISTC ENT('&STR(&DATASET.')) END /* The above code and the word ELSE below was inserted by FDM ELSE IF &LENGTH(&STR(&DATASET)) ^= 0 THEN + DO SET USED = LISTRP IF &STR(&PREFIX.) ^= &STR(&SYSUID.) THEN + SET USED = &USED PREFIX(&PREFIX.) IF &STR(&DATASET.)^= &STR() THEN + SET USED = &USED DATASET(&DATASET.) SET DATASET= &STR(&STR(&PREFIX.)&STR(.)&STR(&DATASET.)) SET USED2 = LISTC ENT('&STR(&DATASET.')) SET CATWK = &STR(NO) END ELSE DO SET USED = LISTRP PREFIX(&PREFIX.) SET DATASET = &STR(&PREFIX.) SET USED2 = LISTC LEVEL(&STR(&DATASET.)) SET CATWK = &STR(YES) END CLS /* clear screen added FDM */ SET USED = &STR(&USED.) &DISPLAY. &TERSE. IF &TERSE.X = TERSEX THEN GOTO TERSE2 WRITE &R. WRITE YOU ISSUED THE FOLLOWING COMMAND&STR(:) WRITE &R. ===> TSO &USED. WRITE &R. WRITE Commands issued by LISTRP and merged + to create the LISTRP listing: WRITE &R. &USED2. WRITE &R. SEARCH MASK(&PREFIX..) WRITE &R.Issued by LISTRP if DISPLAY is used, or found possible + unprotected datasets: WRITE &R. LD DATASET('dataset') AUTH WRITE Syntax of LISTRP: WRITE &R. DATASET(tso.qualified.dsn) and/or PREFIX(prefix), or one of WRITE &R. E(fully.qualified.pattern) | L(dsn.level) | Q(fully.qualified.dsn) WRITE &R. DISPLAY -- display content of PROFILE(S) WRITE ================================================================ TERSE2: SET NOP = NOP IF &LENGTH(&STR(&Q)) ^= 0 THEN DO SET CHK = &SYSDSN('&Q.') IF OK ^= &CHK THEN DO WRITE WRITE A check using &&SYSDSN('&Q.') shows WRITE -- &CHK. END END /********************************************************************** /* Populate the PROFILE list -- SEARCH -- total into COUNT * /********************************************************************** /* GENERIC WAS ADDED ALSO BY FDM */ CONTROL NOFLUSH SEARCH MASK(&PREFIX..) CLIST NOLIST GENERIC SCAN: + ALLOC DD(PROFS) DA(EXEC.RACF.CLIST) SHR OPENFILE PROFS INPUT /*IF &STR() ^= &STR(&IGNORE.) THEN GOTO NOERR1 ERROR DO SET &CC = &LASTCC IF &CC = 400 THEN GOTO EOFPROFS IF &CC > 12 AND &CC ^= 400 THEN DO WRITE ERROR BLOCK ONE ENTERED WITH &CC ERROR END RETURN END NOERR1: SET NOP = NOP SET COUNT = 0 DO WHILE 1=1 GETFILE PROFS /* READ A PROFILE SET COUNT = &COUNT + 1 SET X = &LENGTH(&PROFS) DO WHILE &SUBSTR(&X,&PROFS) ^= &STR(') SET X = &X - 1 END SET &ITEM = &STR(PROF&COUNT) SET &&ITEM = &SUBSTR(10:&X-1,&PROFS) END EOFPROFS: + CLOSFILE PROFS FREE F(PROFS) CONTROL NOMSG DELETE EXEC.RACF.CLIST CONTROL MSG /********************************************************************** /* Populate the DATASET list LISTCAT or put in single dsname * /********************************************************************** IF &CATWK = &STR(NO) THEN + DO SET COUNT2 = 1 /* ONE DATA SET NAME TO PROCESS SET &ITEM2 = &STR(DS&COUNT2) SET &&ITEM2 = &STR(&DATASET) GOTO COMP END CATWORK: + ALLOC F(ALTFILE) NEW REUSE SP(1,1) TR RECFM(V,B,A) LRECL(125) + BLKSIZE(6290) &USED2. OFILE(ALTFILE) /* LISTCAT ----- */ OPENFILE ALTFILE INPUT /*IF &STR() ^= &STR(&IGNORE.) THEN GOTO NOERR3 ERROR DO SET &CC = &LASTCC IF &CC = 400 THEN GOTO EOFSYSP ERROR IF &CC > 12 AND &CC ^= 400 THEN + WRITE ERROR BLOCK ONE ENTERED WITH &CC RETURN END NOERR3: SET NOP = NOP SET COUNT2 = 0 DO WHILE 1=1 GETFILE ALTFILE SET LISTCR = &LISTCR + 1 /* fix this someday needs more than just NONVSAM ------*/ IF &SUBSTR(2:8,&STR(&ALTFILE )) =NONVSAM THEN + DO SET &DSN=&SUBSTR(18:&LENGTH(&ALTFILE),&ALTFILE) SET COUNT2 = &COUNT2 + 1 SET &ITEM2 = &STR(DS&COUNT2) SET &&ITEM2 = &STR(&DSN) END END EOFSYSP: SET NOP = NOP /********************************************************************** /* Two lists are now stored PROFILE and DSNAMES, we now cycle * /* through the PROFILE list and the DSNAMES will be in inner cycle. * /* cycle through the PROFILE list * /********************************************************************** CLOSFILE ALTFILE COMP: SET NOP = NOP /*IF &STR() ^= &STR(&IGNORE.) THEN GOTO NOERR5 ERROR OFF ERROR DO SET &CC = &LASTCC IF ( &CC > 12 AND &CC ^= 400 AND &CC ^= 368 ) THEN DO WRITE ERROR BLOCK TWO ENTERED WITH &CC ERROR END RETURN END NOERR5: SET NOP = NOP SET START=&LENGTH(&PREFIX) + 2 SET RUNNER = 1 DO WHILE (&RUNNER <= &COUNT) SET MATCHDS = &STR(NO) /* INITIALIZE MATCH INDICATOR TO NO */ SET PROFILE = &&PROF&RUNNER SET PROFP = &PROFP. + 1 SET PMATCH = 0 /* NUMBER OF MATCHES FOR ONE PROFILE */ SET PL = &LENGTH(&STR(&PROFILE)) /* SET SCAN LIMIT FOR PROFILE /***************************************************************** /* inner cycle going through DATASETS for each PROFILE * /***************************************************************** SET RUNNER2 = 1 DO WHILE (&RUNNER2 <= &COUNT2) SET DATASET = &&DS&RUNNER2 IF &DATASET = &STR(9) THEN GOTO BYPASSDS /* Could be protected by additional profiles, */ /* we will not list them again even if more restrictive*/ /**------------- create PSEUDO comparison of PROFILE to dsn--*/ SET DL = &LENGTH(&STR(&DATASET)) /* SET SCAN LIMIT SET DC = &START SET PC = &START SET PSEUDO = &STR(&STR(&PREFIX)&STR(.)) DO WHILE (&PC <= &PL) IF &SUBSTR(&PC,&PROFILE) = &STR(%) THEN + DO IF (&DC <= &DL) THEN + SET &PSEUDO = &STR(&PSEUDO&SUBSTR(&DC,&DATASET)) SET &PC = &PC + 1 SET &DC = &DC + 1 GOTO ENDMAIN END IF ( &SUBSTR(&PC,&PROFILE) = &STR(*) AND &PC = &PL ) THEN + DO IF (&DC <= &DL) THEN + SET &PSEUDO = &STR(&PSEUDO&SUBSTR(&DC:&DL,&DATASET)) SET &DC = &DL SET &PC = &PC + 1 GOTO ENDMAIN END IF ( &SUBSTR(&PC,&PROFILE) = &STR(*) AND &PC < &PL ) THEN + DO IF (&DC <= &DL) THEN + DO SET DCR = &DC /* SET CURRENT DSN RANGE TO CURRENT DS POIN DO WHILE (&SUBSTR(&DCR,&DATASET) ^= &STR(.) AND &DCR < &DL) SET &DCR = &DCR + 1 END SET &PSEUDO = &STR(&PSEUDO&SUBSTR(&DC:&DCR-1,&DATASET)) END SET &PC = &PC + 1 SET &DC = &DCR GOTO ENDMAIN END SET &PSEUDO = &STR(&PSEUDO&SUBSTR(&PC,&PROFILE)) SET &PC = &PC + 1 SET &DC = &DC + 1 ENDMAIN: + SET PLEN=&LENGTH(&PSEUDO) IF &PLEN > &DL THEN SET PLEN=&DL IF &PSEUDO ^= &SUBSTR(1:&PLEN,&DATASET) THEN SET PC = &PL + 1 END /* END OF PSEUDO NAME BUILD LOOP /**--------- now do PSEUDO comparison of PROFILE to dsn--*/ IF &STR(&PSEUDO) = &STR(&DATASET) THEN + DO SET MATCHDS = &STR(YES) SET PMATCH = &PMATCH + 1 SET PMATCHT = &PMATCHT + 1 SET LISTCP = &LISTCP. + 1 IF &CATWK.=NO THEN + DO IF &PMATCHT = 1 THEN DO IF X&TERSE. = X OR DISPLAY = &DISPLAY THEN + SET SINGLELD = LD DA('&STR(&PROFILE.)') AUTH WRITE WRITE CATALOGED DATA SET ==> &DATASET WRITE &R PROTECTED BY PROFILE ==> &PROFILE END ELSE WRITE &R UNAFFECTED BY ... ==> &PROFILE /*GOTO REALEND -- WILL BE CHECKING ALL PROFILES NOW END ELSE + DO IF &PMATCH = 1 THEN DO WRITE IF &DISPLAY = DISPLAY THEN + DO WRITE * * * * * * * * * * * * * * * * * * * * * * * * * LD DA('&PROFILE.') AUTH END ELSE WRITE PROFILE ==> &PROFILE WRITE PROTECTS THE FOLLOWING CATALOGED DATA SET(S) END /* MATCH = 1 */ /******/ WRITE DATA SET ====> &DATASET NEXTDS: + SET &ITEM2 = &STR(DS&RUNNER2) /* MARK DATA SET SET &&ITEM2 = &STR(9) /* AS MATCHED END END BYPASSDS: + SET RUNNER2 = &RUNNER2 + 1 /* ADVANCE TO NEXT DATA SET NAME END IF (&MATCHDS = NO AND &CATWK =YES) THEN + IF &LENGTH(&STR(&E.)) = 0 THEN + DO WRITE WRITE NO DATASETS IN USE FOR PROFILE -- &PROFILE. END NEXTPROF: + SET RUNNER = &RUNNER + 1 /* ADVANCE TO NEXT PROFILE END /********************************************************************** /* All profiles have be checked to see if they protect datasets * /* or not. A final report will be produced with the unprotected * /* datasets. * /********************************************************************** IF &TERSE.X = X THEN RETURN IF (&PMATCHT = 0 AND &CATWK = NO THEN + DO WRITE WRITE DATA SET ==> &DATASET NOT RACF PROTECTED WRITE END IF &CATWK = &STR(YES) THEN + DO SET RUNNER = 1 SET FTIME = YES DO WHILE &RUNNER <= &COUNT2 SET DATS = &&DS&RUNNER IF &DATS ^= &STR(9) THEN + DO SET RACFU = &RACFU. + 1 /******/ IF &FTIME = YES THEN + DO WRITE WRITE THE FOLLOWING DATA SET(S) ARE NOT RACF PROTECTED + OR NOT ACCESSIBLE BY YOU. END SET RACFP = &RACFP. + 1 /* WRITE UNPROTECTED DATA SET ===> &DATS IF &RUNNER. > 204 THEN WRITE POSSIBLE + POSSIBLE UNPROTECTED DATA SET ===> &DATS. ELSE DO SET SYSOUTTRAP = 1 LD DATASET('&DATS.') AUTH SET SYSOUTTRAP = 0 IF &SUBSTR(1:11,&STR(&SYSOUTLINE1.)) = &STR(INFORMATION) + THEN DO SET RACFY = &RACFY. + 1 WRITE &SYSOUTLINE1. END ELSE DO SET RACFN = &RACFN. + 1 WRITE &SYSOUTLINE1. END END NEXTQUEST: + SET FTIME = NO END SET RUNNER = &RUNNER + 1 END IF &RACFP. ^= 0 THEN DO WRITE WRITE CONCERNING THE POSSIBLY UNPROTECTED DATASETS... WRITE &R. OF &RACFP. DATASETS HAVE LOOKED AT + &EVAL(&RACFY. + &RACFN.) DATASETS + AND &RACFY. OF THOSE WERE RACF PROTECTED. IF &LENGLVL ^= 0 THEN + WRITE &R. &RACFU. CHECKED FOR LEVEL MATCHES, FIRST END END REALEND: + IF &STR(&SINGLELD.) ^= &STR() THEN &SINGLELD. IF NO = &CATWK THEN EXIT WRITE WRITE LISTRP COMPLETED -- &USED. WRITE &R. PROCESSED &PROFP. OF &COUNT. RECORDS IN PROFILE WRITE &R. PROCESSED &LISTCP OF &COUNT2 RECORDS FROM LISTCAT WRITE LISTRP -- BEGAN &SAVED. -- ENDED &SYSDATE. &SYSTIME. EXIT /* /********************************************************************** /* ICHRTX00 TITLE 'MVS Router exit for JOB verification.'