10 !CHANGE VERSION 6B EDIT 0 27-AUG-77 3 !29-Aug-77 Comments added for DECUS submission. 20 !INTSRUCTIONS: !This program allows non-privelged users to change their own password, !it also allows priveleged persons the ability to lookup info about !any user number and to change passwords or quotas. This program !interacts with $ACCT.VIR and should always be used for password/quota !changes if $ACCT.VIR is to accurately reflect the current status !of accounts on disk. DO NOT USE $UTILTY TO CHANGE PASSWORDS OR !QUOTAS IF YOU PLAN TO USE "LIST" OPTION OF REACT--$UTILTY DOES NOT !UPDATE $ACCT.VIR. ! !For non-priveleged users, instructions are in the file CHANGE.DOC. !For priveleged users the Inspect option allows for looking up old !passwords, quotas, and disk usage; Change option allows either !password and/or quota to be changed. When changing passwords !and/or quotas, hitting just a keeps the old value. !A CTRL/Z backs up to the Inspect or Change question, CTRL/C exits !the program. ! !If an attempt is made to change a password of an account not in !$ACCT.VIR, and error file with extension .ERR is created on [1,4] !stating the ppn and when the attempt was made. Update mode is !used when opening $ACCT.VIR in case several people are doing this !at the same time. Conceivably the program could hang with a !disk block interlock (err=19) or protectection violation(err=10) !if REACT or MONEY is running when a user trys to run this program; !however, we have not had this happen. 400 !VARIABLE DEFINITION ! !P1% PROJ# !P0% PROG# !P% SWAP(PROJ#)+PROG# 900 DIM M%(30%),M1%(30%) !ARRAYS FOR CHANGE STRINGS IN SYS() CALLS. 910 DIM#1%, A%(1023%,4%) !VIRTUAL ARRAY CONTAINING ACCOUNT INFO: !(0,0) # OF ACCOUNTS !(0,1) N%, WHERE DATE$(N%) IS DATE OF LAST RESET. ! 911 !(I,0) P,PN IN PEEK(PEEK(520)+26) FORMAT !(I,1) PASSWORD IN RAD50 (PT1) !(I,2) " (PT2) !(I,3) QUOTA !(I,4) UFD CLUSTER 1000 ON ERROR GOTO 19000 \M$=SYS(CHR$(6%)+CHR$(-7%)) \PRINT 'CHANGE V6B-00' \Q3$=CHR$(13%)+CHR$(10%) \OPEN '$ACCT.VIR' FOR INPUT AS FILE 1%, MODE 1% \A0%=A%(0%,0%) \UNLOCK #1% !IDENTIFY AND INIT OURSELF. 1010 P%=PEEK(PEEK(PEEK(520%)+8%)+24%) \P0%=P% AND 255% \P1%=SWAP%(P%) AND 255% \GOTO 2000 UNLESS P1%=1% !NON-PRIVELEGED USERS CAN ONLY CHANGE THEIR OWN PASSWORD. 1020 INPUT 'INSPECT OR CHANGE';I$ \I$=LEFT(CVT$$(I$,255%),1%) \IF I$='I' THEN I1%=1% ELSE IF I$='C' THEN I1%=2% ELSE 1020 !FORCE A VALID REPSONSE (PRIVELEGED PEOPLE ONLY GET HERE.) 1030 INPUT 'P,PN';P1%,P0% \GOSUB 11000 \ON I1% GOSUB 1100,1200 \GOTO 1030 !CYCLE HERE BASED ON I/C UNTIL CTRL/Z TYPED. 1100 ! ! I N S P E C T (P R I V E L E G E D ) ! 1110 M%(2%)=14% \M%(7%)=P0% \M%(8%)=P1% \CHANGE M% TO M$ \CHANGE SYS(M$) TO M% !14 - ACCOUNTING INFO LOOKUP 1120 PRINT Q3$;FNP0$(P1%,P0%);TAB(10%);RAD$(M%(9%)+SWAP%(M%(10%))); RAD$(M%(11%)+SWAP%(M%(12%)));TAB(20%); 'QUOTA=';M%(27%)+SWAP%(M%(28%));TAB(35%); 'IN USE=';M%(5%)+SWAP%(M%(6%));TAB(50%); 'UFD=';M%(29%) 1130 RETURN !PRINT OUT INFO FROM ACCOUNT DUMP SYS CALL AND RETURN. !NOTE: INFO PRINTED IS ONLY THAT PART WHICH IS NEEDED HERE; REST !PRINT USING '$MONEY'. 1200 ! ! C H A N G E P A S S W O R D / Q U O T A ! 1210 INPUT 'NEW PASSWORD';P$ \ P$=CVT$$(P$,255%) \INPUT 'NEW QUOTA';Q$ \ Q$=CVT$$(Q$,255%) \Q%=VAL(Q$) !ALLOW A PRIVELEGED USER TO TO CHANGE EITHER OR BOTH; !IMPLIES NO CHANGE. 1220 IF LEN(P$) THEN CHANGE SYS(CHR$(6%)+CHR$(-10%)+P$) TO M1% \M%(I%+2%)=M1%(I%) FOR I%=7% TO 10% !STORE RAD50 OF NEW PASSWORD IF GIVEN; NONE IMPLIES NO CHANGE. 1230 IF LEN(Q$) THEN M%(21%)=255% \M%(13%)=Q% AND 255% \M%(14%)=SWAP%(Q%) AND 255% !STORE NEW QUOTA IF GIVEN; NONE IMPLIES NO CHANGE. 1240 M%(2%)=8% \M%(7%)=P0% \M%(8%)=P1% \CHANGE M% TO M$ \M$=SYS(M$) !CHANGE PASSWORD/QUOTA SYS() CALL. 1250 P%=P0%+SWAP%(P1%) \GOSUB 12000 \GOSUB 13000 \RETURN !RETURN AFTER DOING LOOKUP IN $ACCT.VIR (12000) AND MAKING CHANGES !(13000). 2000 ! ! N O N - P R I V E L E G E D U S E R ! 2010 M$=SYS(CHR$(3%)) \PRINT 'OLD PASSWORD? '; \OPEN 'KB:' FOR INPUT AS FILE 2% \CHANGE SYS(CHR$(6%)+CHR$(14%)+STRING$(4%,0%)+CHR$(P0%)+CHR$(P1%)) TO M1% !DISABLE ECHO AND GET ACCOUNT INFO WHILE WAITING. 2020 INPUT#2%, P$ \PRINT \M$=SYS(CHR$(2%)) \CHANGE SYS(CHR$(6%)+CHR$(-10%)+P$) TO M% \F%=0% \F%=-1% IF M%(I%-2%)<>M1%(I%) FOR I%=9% TO 12% \GOTO 2040 UNLESS F% !MAKE SURE OLD PASSWORD MATCHES. 2030 PRINT Q3$;'?ERROR -- OLD PASSWORD INVALID.' \GOTO 8000 !COME HERE IF ERROR. 2040 M$=SYS(CHR$(3%)) \PRINT 'NEW PASSWORD? '; \GOSUB 12000 \INPUT#2%, P$ \PRINT \M$=SYS(CHR$(2%)) !LOOKUP PPN IN $ACCT.VIR WHILE AWAITING INPUT. 2050 CHANGE SYS(CHR$(6%)+CHR$(-10%)+P$) TO M1% \GOSUB 11000 \M%(2%)=8% \M%(7%)=P0% \M%(8%)=P1% \M%(I%+2%)=M1%(I%) FOR I%=7% TO 10% !SET UP STRING FOR CHANGE PASSWORD SYS() CALL. 2060 CHANGE M% TO M$ \M$=SYS(M$) \GOSUB 13000 \GOTO 8000 !DO THE SYS() CALL AND UPDATE $ACCT.VIR, THEN EXIT. ! ! E N D O F M A I N P R O G R A M ! 8000 CLOSE 1%,2% \I$=SYS(CHR$(9%)) !CLOSE FILES AND EXIT TO MONITOR 'READY' MESSAGE. 10000 ! ! F U N C T I O N S & S U B R O U T I N E S ! 10100 DEF FNP0$(P1%,P0%)=CVT$$('['+NUM$(P1%)+','+NUM$(P0%)+']',2%) !PRINT P,PN IN PACKED FORM WITH BRACKETS. 10200 DEF FNE$(E%)=CVT$$(RIGHT(SYS(CHR$(6%)+CHR$(9%)+CHR$(E%)),3%),4%) !PRINT AN ERROR MESSAGE. 11000 M%(M%)=0% FOR M%=2% TO 30% \M%(0%)=30% \M%(1%)=6% \RETURN !SUBROUTINE TO INITIALIZE M%() ARRAY PRIOR TO LOADING FOR SYS() CALL. ! 12000 ! ! L O O K U P P , P N I N $ A C C T . V I R ! 12010 J%=A0% \J%=J%-1% UNTIL A%(J%,0%)=P% \UNLOCK #1% \RETURN IF J% !SCAN BACKWARDS THRU $ACCT.VIR; ERR=55 OR J=0 IMPLIES PPN NOT IN !FILE, SO NOTIFY. 12020 OPEN '[1,4]'+NUM$(P1%)+NUM$(P0%)+'.ERR' FOR OUTPUT AS FILE 3% \PRINT #3%, FNP0$(P1%,P0%);' NOT IN $ACCT.VIR WHEN $CHANGE RAN ON '; DATE$(0%);' AT ';TIME$(0%) \CLOSE 3% \PRINT CHR$(7%); \RETURN !ERROR RECORDED 13000 ! ! R E C O R D C H A N G E S I N $ A C C T . V I R ! 13010 IF LEN(P$) THEN A%(J%,1%)=M%(9%)+SWAP%(M%(10%)) \A%(J%,2%)=M%(11%)+SWAP%(M%(11%)) !STORE NEW PASSWORD IN RAD50 IF IT HAS CHANGED. 13020 A%(J%,3%)=Q% IF LEN(Q$) \UNLOCK #1% \RETURN !STORE NEW QUOTA (IF CHANGED) AND RETURN. 19000 ! ! E R R O R R O U T I N E ! 19010 M$=SYS(CHR$(2%)) \IF ERR=28% THEN RESUME 8000 ELSE RESUME 19020 !GET OUT IN A HURRY IF CTRL/C TYPED. 19020 P9%=SWAP%(PEEK(PEEK(PEEK(520%)+8%)+24%)) AND 255% \IF ERR=11% THEN IF P9%=1% THEN 1020 ELSE 8000 !PRIVELEGED PEOPLE RETURN TO MAIN QUERRY IF CTRL/Z TYPED. 19030 IF ERR=2% THEN PRINT Q3$;'?ERROR -- BAD PASSWORD; TRY AGAIN.';Q3$ \GOTO 1210 IF ERL=1220% \GOTO 2010 IF ERL=2020% \GOTO 2040 IF ERL=2050% !BAD P$ IN SYS(6 + -10) CALL. 19040 IF ERR=52% THEN PRINT Q3$;FNE$(ERR);Q3$ \GOTO 1210 !VAL() ERROR FOR QUOTA. 19050 IF ERR=5% THEN PRINT Q3$;'?ERROR -- NO ACCOUNT ';FNP0$(P1%,P0%);Q3$ \GOTO 1020 IF P9%=1% !NON-EXISTENT P,PN; TRY AGAIN IF PRIVELEGED, FATAL ERROR IF NOT. 19060 IF ERR=50% THEN PRINT Q3$;FNE$(ERR);Q3$ \GOTO 1020 IF P9%=1% !DATA FORMAT ERROR WHILE TYPING THE P,PN DESIRED. 19070 IF ERR=19% THEN SLEEP 2% \IF ERL>=13000% THEN GOTO 13000 ELSE IF ERL>=12000% THEN GOTO 12000 ELSE GOTO 19080 !ERR=19 IS DISK BLOCK INTERLOCK; SLEEP AND GOTO TO CORRECT LOOP. 19075 IF ERR=10% THEN PRINT'Unable to change password now--'; 'Try again in a few moments.' \GOTO 8000 !ERR=10 IS PROTECTION VIOLATION ON OPEN OF $ACCT.VIR-IMPLIES !SOMEBODY ELSE (LIKE REACT OR MONEY) HAS IT OPEN. CAN ONLY !TRY AGAIN LATER. 19080 PRINT Q3$;FNE$(ERR);' (';ERR;') AT LINE';ERL;Q3$; 'FATAL PROGRAM ERROR -- SHOW OUTPUT TO MR. KRUPP.';Q3$ \CLOSE 1%,2% \GOTO 32767 !ANYTHING ELSE IS A DISASTER. 32767 END