1 ! ! S C A N 2! Program: SCAN 3! Version: V02A 4! Edit: 01 7! Edit Date: 19-May-80 9! Author: Brant Cheikes/Dr. Terry F. O'Dwyer 15 EXTEND ! Set up BASIC-PLUS EXTEND mode processing 20 ! & & & ! M o d i f i c a t i o n H i s t o r y & & & ! Version/Edit Edit Date Reason & 21! V02A-01 19-May-80 New release & 50 ! & & & ! P r o g r a m D e s c r i p t i o n & & & 60 ! SCAN is designed to scan any given system disk device for & ! possible security hazards. SCAN produces a list of all files & ! on the specified disk that have temporary privileges; this & ! allows the system manager to check the listed files to make & ! sure that they indeed should have temporary privs. Also, SCAN & ! creates a PIP.SAV command file which renames all files with temp & ! privs to non-priv'd files of the same name. The system manager & ! simply has to edit out all the commands pertaining to files which & ! should indeed have privileges and pass the remaining commands in & ! the file to PIP, with a command like: PIP @. & ! & ! Along with checking for files with privs, SCAN also checks all & ! (except system and privileged accounts) for high or unlimited & ! quotas. A 'high' quota can be defined by the user. The user & ! simply tells SCAN the maximum quota that can be ignored in the & ! system scan. This capability aids the system manager in disk & ! and account management. & ! & ! Finally, SCAN also produces a listing of all accounts on the & ! specified disk device which have violated their quota. Though & ! normally no accounts should show up in this listing, should one & ! appear, it might indicate that there is a break in system security & ! by which means a user can log out while over his quota. & ! & ! SCAN normally runs detached (if the user desires) while performing & ! its processing. However, if SCAN is running on a pseudo keyboard, & ! it will not allow a detach (it could be a BATCH job). & ! & ! This program was originally written by Dr. Terry F. O'Dwyer, Dean & ! of Instruction for Learning Resources of Nassau Community College. & ! The current version of SCAN was written by Brant Cheikes, TEAORE. & ! & 900 ! & & & ! D i m e n s i o n S t a t e m e n t s & & & 910 DIM M%(30%) & ! Matrix for usage with SYS calls & 1000 ! & & & ! M a i n P r o g r a m C o d i n g & & & 1010 V$ = "V02A-01" & ! Set up version/edit level & 1020 ON ERROR GOTO 30000 & \ PRINT & \ PRINT "SCAN "+V$+" "+ & CVT$$(RIGHT(SYS(CHR$(6%)+CHR$(9%)),3%),4%) & \ PRINT "System Security Scanner" & \ PRINT & \ KB% = ASCII(MID(SYS(CHR$(6%)+CHR$(26%)),4%,1%)) & ! Set standard error trap; output the system header & ! Get our KB number & 1030 INPUT "Device to scan? ";DEV$ & \ DEV$ = "SY:" UNLESS LEN(DEV$) & \ DEV$ = DEV$ + ':' UNLESS INSTR(1%,DEV$,':') & \ CHANGE SYS(CHR$(6%)+CHR$(-10%)+DEV$) TO M% & \ S1% = M%(29%)+SWAP%(M%(30%)) & ! Get the device to scan and check it for validity & 1040 GOTO 1050 IF S1% >= 0% & \ DEV$ = RAD$(M%(23%)+SWAP%(M%(24%)))+ & RAD$(M%(25%)+SWAP%(M%(26%))) & \ GOTO 1060 & ! See if a logical name was translated; if so, get the name else & ! get the actual device name & 1050 DEV$ = CHR$(M%(23%))+CHR$(M%(24%)) & \ DEV$ = DEV$ + NUM1$(M%(25%)) IF M%(26%) = 255% & ! Get the device name; add a unit number if one was specified & 1060 INPUT "Maximum ignored quota? <400> ";QUOTA% & \ QUOTA% = 400% UNLESS QUOTA% & ! Get the maximum quota to ignore during scan & 1070 PRINT "Output file for temporary privilege data? "; & \ INPUT LINE PRIV$ & \ PRIV$ = CVT$$(PRIV$,2%+4%) & \ PRIV$ = "TMPPRV.DAT" UNLESS LEN(PRIV$) & ! Get the file in which data on files with temporary privileges is & ! to be stored & 1080 PRINT "PIP command file? <";DEV$;".CMD> "; & \ INPUT LINE CMD$ & \ CMD$ = CVT$$(CMD$,2%+4%) & \ CMD$ = DEV$+'.CMD' UNLESS LEN(CMD$) & ! Get the file for PIP commands to rename files with temp privs to & ! non-priv'd files & 1090 PRINT "File for quota data? "; & \ INPUT LINE QUOTA$ & \ QUOTA$ = CVT$$(QUOTA$,2%+4%) & \ QUOTA$ = "QUOTA.DAT" UNLESS LEN(QUOTA$) & ! Get the filespec for where to store high quota information & 2000 PRINT "File for quota violation data? "; & \ INPUT LINE QUOVIO$ & \ QUOVIO$ = CVT$$(QUOVIO$,2%+4%) & \ QUOVIO$ = "QUOVIO.DAT" UNLESS LEN(QUOVIO$) & ! Get the filename for where to store data on accounts that have & ! violated their quota in some way & 2010 INTERFACE% = ASCII(MID(SYS(CHR$(6%)+CHR$(16%)+CHR$(0%)+ & CHR$(255%)),19%,1%)) & \ IF INTERFACE% = 8% THEN PRINT & \ PRINT "**** No detach from pseudo keyboard ****" & \ DETACH% = 0% & \ GOTO 2030 & ! If we are on a pseudo keyboard (check interface type), do not & ! allow a detach; skip next query & 2020 INPUT "Detach? ";DETACH$ & \ DETACH$ = LEFT(DETACH$,1%) IF LEN(DETACH$) & \ IF DETACH$ = "Y" OR LEN(DETACH$) = 0% THEN DETACH% = -1% ELSE & IF DETACH$ = "N" THEN DETACH% = 0% ELSE PRINT "Please answer"+ & " Y[ES] or N[O]." & \ PRINT & \ GOTO 2020 & ! See if user wants to detach & 2030 OPEN PRIV$ + "<60>" FOR OUTPUT AS FILE 1% & \ OPEN CMD$ + "<60>" FOR OUTPUT AS FILE 2% & \ OPEN QUOTA$ + "<60>" FOR OUTPUT AS FILE 3% & \ OPEN QUOVIO$ + "<60>" FOR OUTPUT AS FILE 4% & \ OPEN "NL:" AS FILE 5%, RECORDSIZE 81% & \ DEV$ = DEV$ + ':' & \ FIELD #5%, 80% AS LIN$ & \ FIELD #5%, 10% AS NAM.EXT$, & 9% AS SIZ$, & 8% AS PROTEC$, & 13% AS ACC$, & 13% AS DAT$, & 9% AS TIM$, & 7% AS CLU$, & 11% AS UST$ & ! Open all files; set up valid device specification; field the & ! null device buffer for directory file header & 2040 PRINT & \ PRINT "SCAN started at ";CVT$$(TIME$(0%),2%);" on ";DATE$(0%) & \ PRINT & \ PRINT "Device ";DEV$;" being scanned" & \ PRINT & \ IF DETACH% THEN PRINT "Detaching..." & \ PRINT CHR$(12%) & \ SYSCAL$ = SYS(CHR$(6%)+CHR$(7%)+CHR$(128%)) & ! Print starting header; detach if necessary & 3000 ! & & & ! S e t U p F i l e H e a d e r s & & & 3010 PRINT #1% & \ PRINT #1% PRIV$;" - listing of all files with temporary privileges" & \ PRINT #1% & \ PRINT #1% "Created by SCAN on ";DATE$(0%);" at "; & CVT$$(TIME$(0%),2%) & \ PRINT #1% & \ PRINT #1% "Structure scanned: ";DEV$ & \ PRINT #1% CHR$(12%) & ! Set up the file header for file 1 & 3020 PRINT #2% ";" & \ PRINT #2% "; ";CMD$;" - PIP command file to remove temp privs" & \ PRINT #2% ";" & \ PRINT #2% "; Structure scanned: ";DEV$ & \ PRINT #2% ";" & 3030 PRINT #3% & \ PRINT #3% QUOTA$;" - listing of all accounts with high or "+ & "unlimited quotas" & \ PRINT #3% & \ PRINT #3% "'HIGH' means greater than ";NUM1$(QUOTA%);" blocks" & \ PRINT #3% & \ PRINT #3% "Created by SCAN on ";DATE$(0%);" at "; & CVT$$(TIME$(0%),2%) & \ PRINT #3% & \ PRINT #3% "Structure scanned: ";DEV$ & \ PRINT #3% CHR$(12%) & \ PRINT #3% "Account";TAB(20%);"Quota";TAB(32%);"UFD" & \ PRINT #3% & 3040 PRINT #4% & \ PRINT #4% QUOVIO$;" - listing of all accounts over their quota" & \ PRINT #4% & \ PRINT #4% "Structure scanned: ";DEV$ & \ PRINT #4% CHR$(12%) & 3100 GOTO 4000 IF DETACH% & \ PRINT CVT$$(TIME$(0%),2%);", ";DATE$(0%);": all files open"; & \ PRINT " **** SCAN beginning ****" & \ PRINT & ! Having set up files, skip ahead if detached else print information & 4000 ! & & & ! S c a n T h e S p e c i f i e d D e v i c e & & & 4010 CHANGE SYS(CHR$(6%)+CHR$(-10%)+DEV$) TO M% & ! Put the device specification into the matrix & 4020 FOR INDEX% = 1% TO 32767% & ! Set up the SYS call loop index & 4030 M%(0%) = 30% & \ M%(1%) = 6% & \ M%(2%) = 14% & \ M%(3%) = INDEX% & \ M%(4%) = SWAP%(INDEX%) & \ M%(5%) = 0% & \ M%(6%) = 0% & \ CHANGE M% TO M$ & \ CHANGE SYS(M$) TO M% & \ P1% = M%(8%) & \ P2% = M%(7%) & \ GOTO 4060 IF P1% < 2% & ! Set up for account lookup on index; skip quota check if a & ! privileged or system account & 4040 QUO = 256. * M%(28%) + M%(27%) & \ QUO.$ = NUM1$(QUO) & \ QUO.$ = ">=65535" IF QUO = 65535. & \ USED = 256. * M%(6%) + M%(5%) & \ UFD$ = NUM1$(M%(29%)) & ! Get quota and used blockage; get UFD clustersize & 4050 GOSUB 10000 IF QUO = 0. OR QUO > QUOTA% & \ GOSUB 10020 IF QUO <> 0. AND (QUO - USED) < 0. & ! If account has no quota or high quota, go log it; check account & ! for quota violations & 4060 FOR LOOP% = 0% TO 32767% & ! Set up loop for directory lookup & 4070 M%(0%) = 30% & \ M%(1%) = 6% & \ M%(2%) = 15% & \ M%(3%) = LOOP% & \ M%(4%) = SWAP%(LOOP%) & \ M%(5%) = P2% & \ M%(6%) = P1% & \ CHANGE M% TO M$ & \ CHANGE SYS(M$) TO M% & \ GOTO 4080 UNLESS (M%(15%) AND 128%) & \ GOSUB 10040 & ! Set up for directory lookup on index call; execute; check file & ! protection code for a set privileged (128) bit set; log if set & 4080 NEXT LOOP% & 4090 FOUND% = 0% & \ NEXT INDEX% & ! Reset found flag/counter; lookup next account & 4500 CLOSE #2% & ! We are finished with the PIP command file & 4510 PRINT #1% & \ PRINT #1% NUM1$(PRIV%);" file";FNS$(PRIV%); & " with temporary privileges" & \ PRINT #1% & \ CLOSE #1% & ! Print total and close up & 4520 PRINT #3% & \ PRINT #3% NUM1$(FLAGGED%);" account";FNS$(FLAGGED%); & " flagged for high or unlimited quota";FNS$(FLAGGED%) & \ PRINT #3% & \ CLOSE #3% & ! Print totals and close up & 4530 PRINT #4% & \ PRINT #4% NUM1$(OVER%);" account";FNS$(OVER%);" over quota" & \ PRINT #4% & \ CLOSE #4% & ! Total and close & 4540 GOTO 5000 IF DETACH% & \ PRINT & \ PRINT "SCAN completed at ";CVT$$(TIME$(0%),2%);" on "; & DATE$(0%) & \ PRINT & \ PRINT NUM1$(INDEX%-1%);" account";FNS$(INDEX%-1%);" scanned on "; & DEV$ & \ PRINT & \ PRINT NUM1$(FLAGGED%);" flagged on quota" & \ PRINT NUM1$(OVER%);" over quota" & \ PRINT NUM1$(PRIV%);" file";FNS$(PRIV%);" with temporary privileges" & \ GOTO 32000 & ! Skip out if detached else print totals and exit & 5000 ! & & & ! C o m m i t S u i c i d e & & & 5010 JOB% = (PEEK(518%) AND 255%)/2% & \ SUICIDE$ = SYS(CHR$(6%)+CHR$(8%)+CHR$(JOB%)+STRING$(24%,0%)+ & CHR$(255%)) & \ STOP & ! We is dead now. & 10000 ! & & & ! S u b r o u t i n e s & & & ! F l a g Q u o t a & & & 10010 PRINT #3% "["+NUM1$(M%(8%))+','+NUM1$(M%(7%))+"]"; & TAB(18%);SPACE$(7%-LEN(QUO.$));QUO.$;TAB(32%);SPACE$(3%-LEN(UFD$)); & UFD$ & \ FLAGGED% = FLAGGED% + 1% & \ RETURN & 10020 ! & & & ! L o g Q u o t a V i o l a t i o n s & & & 10030 PRINT #4% "["+NUM1$(M%(8%))+','+NUM1$(M%(7%))+"] is "; & NUM1$(ABS(QUO-USED));" block";FNS$(ABS(QUO-USED));" over quota of "; & QUO.$;" block";FNS$(QUO) & \ OVER% = OVER% + 1% & \ RETURN & 10040 ! & & & ! H a n d l e F i l e s W i t h P r i v s & & & 10050 GOTO 10070 IF FOUND% & \ FOUND% = -1% & ! See if we must set up header & 10060 HDR$ = " Name .Ext Size Prot Access Date "+ & " Time Clu USTAT" & \ PPN$ = DEV$ + "[" + NUM1$(M%(6%)) + ',' + NUM1$(M%(5%)) + "]" & \ PRINT #1% & \ PRINT #1% PPN$ & \ PRINT #1% HDR$ & ! Print header & 10070 NAM$ = RAD$(M%(7%)+SWAP%(M%(8%)))+ & RAD$(M%(9%)+SWAP%(M%(10%)))+'.'+ & RAD$(M%(11%)+SWAP%(M%(12%))) & \ LSET NAM.EXT$ = NAM$ & \ MSB% = M%(16%) & \ LSB% = M%(13%)+SWAP%(M%(14%)) & \ SIZE$ = NUM1$(MSB%*65536.+32768.+(LSB% EQV 32767%)) & \ RSET SIZ$ = SIZE$ & \ PROT$ = "<"+NUM1$(M%(15%))+">" & \ RSET PROTEC$ = PROT$ & \ ACCESS$ = DATE$(M%(17%)+SWAP%(M%(18%))) & \ RSET ACC$ = ACCESS$ & \ RSET DAT$ = DATE$(M%(19%)+SWAP%(M%(20%))) & \ RSET TIM$ = CVT$$(TIME$(M%(21%)+SWAP%(M%(22%))),2%) & \ RSET CLU$ = NUM1$(M%(27%)+SWAP%(M%(28%))) & \ RSET UST$ = FNBIT$(M%(30%)) & \ PRINT #1% LIN$ & \ LSET LIN$ = STRING$(80%,0%) & ! Print out all that stupid information to that stupid file & 10080 PRINT #2% PPN$;NAM$;"<";NUM1$(M%(15%)-128%);">/RE" & ! Output the PIP command to remove temp privs & 10090 PRIV% = PRIV% + 1% & \ RETURN & ! Increment counter and return & 20000 ! & & & ! F u n c t i o n s & & & 20010 DEF* FNBIT$(X%) & ! Returns USTAT information & 20020 S$ = '' & \ S$ = S$ + "L" IF X% AND 2% & \ S$ = S$ + "Wr" IF X% AND 4% & \ S$ = S$ + "Up" IF X% AND 8% & \ S$ = S$ + "C" IF X% AND 16% & \ S$ = S$ + "P" IF X% AND 32% & \ S$ = S$ + "Mdl" IF X% AND 128% & ! Test the corresponding bits & 20030 FNBIT$ = S$ & \ FNEND & 20040 DEF* FNS$(DUMMY%) & 20050 IF DUMMY% <> 1% THEN FNS$ = "s" ELSE FNS$ = '' & 20060 FNEND & 30000 ! & & & ! E r r o r H a n d l i n g & & & 30010 IF ERL = 1030% AND ERR <> 11% THEN PRINT & "?Invalid device specification" & \ PRINT & \ RESUME 1030 & ! Handle bad device errors & 30020 IF ERL = 2030% THEN PRINT & "?File open error - reenter all filenames" & \ PRINT & \ RESUME 1070 & ! If bad filename, have the poor guy reenter them all & 30030 IF ERL = 4030% THEN RESUME 4500 & ! On account lookup error, we are finished & 30040 IF ERL = 4070% THEN RESUME 4090 & ! On file lookup error, go get another account & 30500 IF ERR = 11% THEN RESUME 32000 & ! Exit on CTRL/Z & 30900 ERROR$ = CHR$(13%)+CHR$(10%)+"?Unexpected error - "+ & CVT$$(RIGHT(SYS(CHR$(6%)+CHR$(9%)+CHR$(ERR)),3%),4%)+ & " (ERR="+NUM1$(ERR)+") at line "+NUM1$(ERL)+CHR$(13%)+CHR$(10%) & \ GOTO 30950 IF DETACH% & \ PRINT ERROR$ & \ RESUME 32000 & 30950 SYSCAL$ = SYS(CHR$(6%)+CHR$(-5%)+CHR$(KB%)+ERROR$) & \ RESUME 5000 & ! Set up error message as a string; if not detached, print it and & ! exit, else broadcast it to the keyboard we detached from & 32000 ! & & & ! E x i t & & & 32600 NO EXTEND ! Disable EXTEND mode processing 32700 S$ = SYS(CHR$(9%)) ! Clear core and exit fast 32767 END