!*********************************************************************** !* !* Command for changing user passwords !* !* Copyright (C) R.D. Eager University of Kent MCMLXXXV !* !*********************************************************************** ! ! !*********************************************************************** !* !* Constants !* !*********************************************************************** ! constantinteger minpass = 6; ! Min length of a password constantinteger maxpass = 11; ! Max length of a password constantlonginteger int mask = x'0002000A0002000A' ! INT: 'A','C','Q','a','c','q' constantstring (1) snl = " " ! ! !*********************************************************************** !* !* Subsystem references !* !*********************************************************************** ! systemroutinespec console(integer ep,integername start,len) systemstring (255)mapspec controlline(integername flag) systemstringfunctionspec itos(integer n) systemroutinespec journaloff systemintegerfunctionspec parmap externalroutinespec prompt(string (255) s) systemroutinespec psysmes(integer root,mess) systemroutinespec reroutecontingency(integer ep,class,longinteger c mask,routine ontrap, integername flag) systemroutinespec setfname(string (63) s) externalroutinespec setmode(string (255) s) systemroutinespec setpar(string (255) s) externalroutinespec set return code(integer i) systemstringfunctionspec spar(integer n) systemroutinespec signal(integer ep,p1,p2,integername flag) systemroutinespec uctranslate(integer ad,len) externalintegerfunctionspec uinfi(integer entry) externalstringfunctionspec uinfs(integer entry) ! ! !*********************************************************************** !* !* Director references !* !*********************************************************************** ! externalintegerfunctionspec dsetpassword(string (6)user,integer fsys, which,string (63) old,new) ! ! !*********************************************************************** !* !* Forward references !* !*********************************************************************** ! routinespec finalise security ! ! !*********************************************************************** !* !* Service routines !* !*********************************************************************** ! routine ontrap(integer class,subclass) integer flag ! flag = 0 finalise security signal(3,class,subclass,flag); ! Get the Subsystem to do the rest end ; ! of ontrap ! !----------------------------------------------------------------------- ! routine initialise security(integername flag) ! Intercept single-character INT: messages, so that the security ! precautions may be unset on exit. ! reroutecontingency(3,65,int mask,ontrap,flag) if flag = 0 then start setmode("-E"); ! Turn off input echo journaloff; ! Turn off any journal finish end ; ! of initialise security ! !----------------------------------------------------------------------- ! routine finalise security integer flag,ad ! setmode("E"); ! Turn on input echo newline ad = 0 console(14,ad,ad); ! Turn on recalling again reroutecontingency(0,0,0,ontrap,flag); ! Cancel contingency rerouting end ; ! of finalise security ! !----------------------------------------------------------------------- ! routine read password(string (63) mes,stringname p,integername flag) stringname line ! printstring(mes); newline prompt(tostring(nl)."Password: ") line == control line(flag) newline if flag # 0 then start setfname("") flag = 202; ! Invalid parameter return finish ! p = line uctranslate(addr(p)+1,length(p)) flag = 0 end ; ! of read password ! ! !*********************************************************************** !* !* P A S S W O R D !* !*********************************************************************** ! externalroutine password(string (255) parms) integer flag,i,c,fore,back string (maxpass) pass1,pass2,oldpass stringname line ! ! Decode and validate any parameter, after disallowing use in OBEY and ! batch. ! if uinfi(2) # 1 then start printstring("Password may only be changed from an interactive terminal") newline flag = 173; ! No access permission -> err3 finish ! setpar(parms) if parmap > 1 then start flag = 263; ! Wrong number of parameters -> err2 finish ! parms = spar(1) uctranslate(addr(parms)+1,length(parms)) line == parms fore = 0 back = 0 cycle for i = 1,1,length(line) cycle c = charno(line,i) if c = 'F' then fore = -1 else c if c = 'B' then back = -1 else start printstring("Parameter not recognised.".snl) fore = 0 back = 0 exit finish repeat exit if fore + back # 0; ! A valid letter was typed printstring("Which password do you want to change?".snl) printstring("(F for foreground, B for background, FB for both)".snl) prompt("F or B or FB: ") line == controlline(flag) if flag # 0 then start line == parms line = "" finish uctranslate(addr(line)+1,length(line)) repeat ! ! Turn off input echo, and disable the session journal, for obvious ! security reasons. ! initialise security(flag) -> err if flag # 0 ! ! Read in the current foreground password (needed by DSETPASSWORD) ! printstring("Passwords will not be echoed.".snl) read password("Type in your current FOREGROUND password.",oldpass,flag) -> err if flag # 0 ! ! Read the new password(s) twice, and check that they were the same both ! times. It is quite likely that the user will not be sure what he typed ! (since input echo is off), so this helps to ensure that he knows what ! he has set the password(s) to. ! cycle if fore # 0 then printstring(snl."Change FORE") else c if back # 0 then printstring(snl."Change BACK") else c exit printstring("GROUND password -".snl) ! read password("Type in your new password -",pass1,flag) -> err if flag # 0 ! if length(pass1) < minpass then start printstring("For security reasons, your password must be at least ".itos(minpass)." characters long".snl) printstring("Please choose another one".snl) continue finish ! if length(pass1) > maxpass then start printstring("Passwords may not be more than ".itos(maxpass)." characters long".snl) printstring("Please choose another one".snl) continue finish ! read password("Please type new password again to confirm -",pass2,flag) -> err if flag # 0 if pass1 # pass2 then start printstring("You gave two different forms for your new password.".snl) printstring("The old password has not been changed.".snl) exit finish ! flag = dsetpassword(uinfs(1),uinfi(1),¬fore,oldpass,pass1) if fore # 0 then fore = 0 else c if back # 0 then back = 0 if flag # 0 then start back = 0 if flag = 8 then start printstring("You did not give your current foreground") printstring(" password correctly.".snl) printstring("The password has not been changed.".snl) flag = 173; ! No access permission -> err4 finish else start flag = flag + 500 -> err finish finish oldpass = pass1 printstring("Password changed.".snl) repeat ! err: finalise security if flag = 1000 then start printstring("The password you typed was too long.".snl) printstring("Passwords may not be more than ".itos(maxpass)." characters long.".snl) -> err4 finish ! err2: if flag # 0 then psysmes(63,flag) ! err3: set return code(flag) return ! err4: finalise security -> err3 end ; ! of password endoffile