From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 13-NOV-1989 22:02
To:	MRGATE::"ARISIA::EVERHART"
Subj:	SYSALF Autologin control 1/2

Message-Id:  <8911132147.AA07191@crdgw1.ge.com>
Received: From NSFNET-RELAY.AC.UK by CRVAX.SRI.COM with TCP; Mon, 13 NOV 89 04:00:35 PDT
Received: from sun.nsfnet-relay.ac.uk by vax.NSFnet-Relay.AC.UK 
           via Janet with NIFTP  id aa01056; 13 Nov 89 9:18 GMT
Date:           Mon, 13 Nov 89   9:24 BST
From: Nick de Smith <"PSI%JANET.000000000040::NICK%ncdlab.ulcc.ac.uk"@NSFnet-Relay.AC.UK>
To: INFO-VAX <@NSFnet-Relay.AC.UK:INFO-VAX@crvax.sri.com>
Subject:        SYSALF Autologin control 1/2

$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.1-004  3-AUG-1989
$!   On  9-NOV-1989 17:46:17.36   By user NICK 
$!
$! This VMS_SHARE Written by:
$!    Andy Harper, Kings College London UK
$!
$! Acknowledgements to:
$!    James Gray       - Original VMS_SHARE
$!    Michael Bednarek - Original Concept and implementation
$!
$!+ THIS PACKAGE DISTRIBUTED IN 2 PARTS, TO KEEP EACH PART
$!  BELOW 30 BLOCKS
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. SYSALF.COM;1
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if f$trnlnm("SHARE_LOG") then $ w = "!"
$ if f$getsyi("version") .ges. "V4.4" then $ goto START
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$UNPACK: SUBROUTINE ! P1=filename, P2=checksum
$ if f$search(P1) .eqs. "" then $ goto file_absent
$ e "-W-EXISTS, File ''P1' exists. Skipped."
$ delete/nolog 'f'*
$ exit
$file_absent:
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'."
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
$ delete/nolog 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");
buff:=CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(buff))
;LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(buff));g:=0;LOOP EXITIF MARK(NONE)=END_OF(buff);x:=
ERASE_CHARACTER(1);IF g = 0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x=
"V" THEN APPEND_LINE;MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;
IF x="+" THEN g:=1;ERASE_LINE;ENDIF;ELSE IF x="-" THEN g:=0;ENDIF;ERASE_LINE;
ENDIF;ENDLOOP;p:="`";POSITION(BEGINNING_OF(buff));LOOP r:=SEARCH(p,FORWARD);
EXITIF r=0;POSITION(r);ERASE(r);COPY_TEXT(ASCII(INT(ERASE_CHARACTER(3))));
ENDLOOP;o:=GET_INFO(COMMAND_LINE,"output_file");WRITE_FILE(buff,o);
ENDPROCEDURE;Unpacker;EXIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create/nolog 'f'
X
X$`009Setv = 'F$Verify( "No" )
X$!+
X$!`009SYSALF.COM`009`009Auto-login to a VAX/VMS V5.x
X$!
X$!`009Author`009`009: Nick de Smith
X$!`009Date`009`009: 31-Aug-89
X$!
X$!`009Edit`009Edit date`009By`009Why
X$!`009 01`00930-Oct-89`009NMdS`009Updated for VMS V5.2 to handle SET HOST
X$!
X$!`009Copyright (c) 1989 by Applied Telematics Group Limited and Nick de SMi
Vth
X$!
X$!`009This software is provided for interest only. It may not be lent,
X$!`009copied or used in any way for the purpose of profit. The author
X$!`009accepts no responsibility for any action that may result from the
X$!`009use of this software.
X$!`009This software may be copied (keeping this copyright notice) and used
X$!`009freely providing the above conditions are observed.
X$!
X$!`009Use of this DCL command file enables control of autologins on a VMS
X$!`009system. If the file SYS$SYSTEM:SYSALF.DAT exists,
X$!`009LOGINOUT will associate any attempt to log in from selected "access po
Vrts"
X$!`009with pre-defined accounts. An "access port" is VMS's attempt to allow
V a
X$!`009program to identify the source of connection to a device. eg. for a DE
VCnet
X$!`009SET HOST command, the access port name is formed from the remote node
V name
X$!`009concatenated with the username of the remote user in the form REMNODE:
V:REMUSER.
X$!`009Any program can determine the access port name for a device by using $
VGETDVI
X$!`009with the DVI$_TT_ACCPORNAM item code which returns a 64 byte, zero fil
Vled, string.
X$!`009In general, access port names are returned for any pseudo terminal dev
Vice in four
X$!`009different forms:
X$!`009`009Access type`009`009Device form`009Access port format
X$!`009`009DECnet SET HOST`009`009RTAn:`009`009remnode::remuser (VMS V5.2 and
V later only)
X$!`009`009PSI X.29 access`009`009NVAn:`009`009network_name.remote_DTE_number
X$!`009`009LAT`009`009`009LTAn:`009`009server_name/port_name_on_server
X$!`009`009PCSA LAT connect`009LTAn:`009`009PC_decnet-node-name
X$!
X$!`009LOGINOUT looks up the access port name for SYS$COMMAND before promptin
Vg for "Username".
X$!`009If the access port name is blank, the "DVI$_TT_FULLDEVNAM" form is fet
Vched. This string
X$!`009is then used as key 1 into the file SYS$SYSTEM:SYSALF.DAT. If the file
V exists, and there
X$!`009is a record matching the key, the VMS username to use is extracted fro
Vm the record.
X$!`009This username is used by LOGINOUT, and the user is not prompted for on
Ve. If the selected
X$!`009username requires a password (or two), the user is still prompted for
V it/them.
X$!
X$!`009This facility is especially useful for attaching terminals with numeri
Vc only keypads to
X$!`009selected software, for controlling SET HOST use by remote DECnet or VA
VX PSI X.29 users, and
X$!`009for tying selected DECserver/LAT ports to specific accounts with autoc
Vonnect.
X$!
X$!`009Note that the username field is key 2 (duplicates allowed), and that y
Vou may list by username.
X$!-
X$`009Set Symbol /Scope=(NoLocal,NoGlobal)`009`009`009`009! Insulate ourselve
Vs
X$!
X$`009Name`009= F$Parse( F$Environment( "PROCEDURE" ),,, "NAME" )
X$`009Info`009= "%" + Name + "-I, "`009`009`009`009`009! Information message
X$`009Warn`009= "%" + Name + "-W, "`009`009`009`009`009! Warning message
X$`009Fatal`009= "%" + Name + "-F, "`009`009`009`009`009! Fatal error message
X$`009Ask`009= "Read SYS$COMMAND /End=End /Prompt="`009`009`009! User prompt
V command
X$`009Say`009= "Write SYS$OUTPUT"`009`009`009`009`009! Print to terminal
X$`009Alfdef`009= "SYS$SPECIFIC:`091SYSEXE`093.DAT"`009`009`009`009! ALF defa
Vults
X$`009TRUE`009= (1.eq.1)`009`009`009`009`009`009! Logical TRUE
X$`009FALSE`009= (1.eq.0)`009`009`009`009`009`009! Logical FALSE
X$`009P_0`009= 0`009`009`009`009`009`009`009! Key 0 position (access port nam
Ve)
X$`009L_0`009= 63`009`009`009`009`009`009`009! Key 0 length
X$`009P_1`009= 63`009`009`009`009`009`009`009! Key 1 position (user name)
X$`009L_1`009= 63`009`009`009`009`009`009`009! Key 1 length
X$`009On CONTROL_Y Then Goto CNTRL_Y`009`009`009`009`009! CTRL/Y forces exit
X$`009On WARNING Then Continue`009`009`009`009`009! All main errors
X$!
X$`009Say ""
X$`009Say Name, " - System auto-logon procedure"
X$`009Say ""
X$!
X$`009If P1 .nes. "" Then Alfdef = P1`009`009`009`009`009! Use argument as de
Vfault
X$`009Sysalf = F$Parse( "SYSALF", Alfdef,,, "SYNTAX_ONLY" )`009`009! Build AL
VF file name
X$`009If F$Search( Sysalf ) .Nes. "" Then Goto OPEN_ALF`009`009! Search for A
VLF file
X$!
X$`009Say Warn, Sysalf," not found"`009`009`009`009`009! Not found - New file
V time
X$`009Say Info, "Creating new file"
X$`009Temp_File = F$Parse( ".FDL;", F$GetJPI( "", "PID" ) )`009`009! Create a
V temp file name
X$`009Fdl = "Write TEMP_FILE"`009`009`009`009`009`009! Shorthand write comman
Vd
X$`009Open /Write /Error=FDL_ERROR TEMP_FILE &Temp_File`009`009! Create a tem
Vp FDL file
X$!
X$`009Fdl "Title`009SYSALF Auto Login Data File"
X$`009Fdl "File"
X$`009Fdl "`009Organization`009`009Indexed"
X$`009Fdl "`009Protection`009`009(s:rwe,o:rwe,g,w)"
X$`009Fdl "`009Owner`009`009`009`091001,004`093"
X$`009Fdl "Record"
X$`009Fdl "`009Size`009`009`009", L_0 + L_1 + 2
X$`009Fdl "Key 0"
X$`009Fdl "`009Name`009`009`009""Access Port Name"""
X$`009Fdl "`009Changes`009`009`009No"
X$`009Fdl "`009Prolog`009`009`0093"
X$`009Fdl "`009Length`009`009`009", L_0
X$`009Fdl "`009Position`009`009", P_0
X$`009Fdl "Key 1"
X$`009Fdl "`009Name`009`009`009""Username"""
X$`009Fdl "`009Changes`009`009`009Yes"
X$`009Fdl "`009Duplicates`009`009Yes"
X$`009Fdl "`009Data_Key_Compression`009Yes"
X$`009Fdl "`009Index_Compression`009Yes
X$`009Fdl "`009Null_Key`009`009Yes"
X$`009Fdl "`009Null_Value`009`009"" """
X$`009Fdl "`009Length`009`009`009", L_1
X$`009Fdl "`009Position`009`009", P_1
X$`009Close TEMP_FILE
X$!
X$`009Create /Fdl=&Temp_File &Sysalf`009`009`009`009`009! Create new sysalf
X$`009Temp = $Status
X$`009Delete 'F$Parse( ";*", Temp_File )`009`009`009`009! Delete the FDL file
X$`009If .not. Temp
X$`009Then`009Say Fatal,"Failed to create """, Sysalf, """"
X$`009`009Goto END
X$`009EndIf
X$`009Set Prot=(s=rwe,o=rwed,g,w) &Sysalf
X$!
X$!`009Open the ALF`009( Auto Login File )
X$!
X$ OPEN_ALF:
X$`009Open /Error=OPEN_FAILED /Share=READ /Read /Write ALF_FILE &Sysalf
X$!
X$`009Say "Type '?' at any prompt for help"
X$!
X$ GET_ACCESS_PORT_NAME:
X$`009On WARNING Then Continue`009`009`009`009`009! All main errors
X$`009Say ""
X$`009Ask "* Access Port Name : " Access_Port_Name`009`009`009! Get access po
Vrt  name
X$`009Access_Port_Name := 'Access_Port_Name`009`009`009`009! Clean up the nam
Ve
X$`009If Access_Port_Name .eqs. "" Then Goto DO_LIST`009`009`009! List all li
Vnes
X$`009If Access_Port_Name .eqs. "?"`009`009`009`009`009! If help wanted...
X$`009Then`009Type /NoPage SYS$INPUT
X
XAt the "Access Port Name" prompt:
X
X`009a) Enter either a physical terminal name, or an access port name.
X
X`009   Format`009`009Example
X`009   Ttcn:`009`009TTA2:`009`009`009! Ordinary terminal
X`009   server/portnam`009SER201/PORT_7`009`009! For LAT calls
X`009   net.dte-address`009PSS.234212300456`009! For X.29 calls
X`009   remnode::remuser`009VX9910::VECTORUSER`009! For SET HOST
X`009   PC_decnet-node-name`009PC_NICKPC`009`009! For PCSA LAT SET HOST
X
X`009b) Press <CR> to list currently controlled access ports.
X$`009`009Goto GET_ACCESS_PORT_NAME`009`009
X$`009EndIf
X$`009If F$Locate( "/", Access_Port_Name ) .ne. F$Length( Access_Port_Name )
V Then Goto GET_USER ! Check for LAT access
X$`009If F$Locate( ".", Access_Port_Name ) .ne. F$Length( Access_Port_Name )
V Then Goto GET_USER ! Check for X.29 access
X$`009If F$Locate( "::", Access_Port_Name ) .ne. F$Length( Access_Port_Name )
V Then Goto GET_USER ! Check for SET HOST
X$`009If F$Locate( "PC_", Access_Port_Name ) .eq. 0 Then Goto GET_USER`009`00
V9`009  ! PC LAT access
X$!
X$!`009Should be a terminal name to get this far
X$!
X$`009If .not. F$GetDVI( Access_Port_Name, "EXISTS" )`009`009`009! Not a real
V device
X$`009Then`009Say Warn, """", Access_Port_Name, """ is not a valid device or
V access port name"
X$`009`009Goto GET_ACCESS_PORT_NAME
X$`009EndIf
X$`009Access_Port_Name = F$GetDVI( Access_Port_Name, "FULLDEVNAM" )`009! Get
V full device name
X$`009If Access_Port_Name .eqs. "" Then Goto GET_ACCESS_PORT_NAME`009! Not a
V true name
X$`009If .not. F$GetDVI( Access_Port_Name, "TRM" )`009`009`009! Check to see
V if its a terminal
X$`009Then`009Say Warn, """", Access_Port_Name, """ is not a terminal"
X$`009`009Goto GET_ACCESS_PORT_NAME
X$`009EndIf
X$!
X$ GET_USER:
X$`009Ask "* Username         : " New_User`009`009`009`009! Get associated us
Ver name
X$`009New_User := 'New_User`009`009`009`009`009`009! Clean up user name
X$`009If New_User .eqs. "" Then Goto DELETE_RECORD`009`009`009! <CR> means za
Vp record
X$`009If New_User .eqs. "?"
X$`009Then`009Type /NoPage SYS$INPUT
X
XAt the "Username" prompt:
X
X`009a) Enter a valid user name to enter/amend a record.
X
X`009b) Enter a blank name to delete a record.
X
X$`009`009Goto GET_USER
X$`009EndIf
X$`009Read /Index=0 /Key=&Access_Port_Name /Error=ADD_RECORD ALF_FILE Record
X$`009`009`009`009`009`009`009`009`009! Read the selected record
X$!
X$!`009Update old record
X$!
X$ UPDATE_RECORD:
X$`009Old_User := 'F$Extract( P_1, L_1, Record )`009`009`009! Get previous us
Ver name
X$`009Say Info,"Access port ", Access_Port_Name, " old user was ", Old_User
X$`009Ask "* Confirm change `091Yes/No`093 : " Yes`009`009`009`009! Confirm a
Vll updates
X$`009If Yes .eqs. "?"
X$`009Then`009Type /NoPage SYS$INPUT
X
X`009Type "YES" to confirm the update, "NO" or RETURN to
X`009abort the change.
X
X$`009`009Goto UPDATE_RECORD
X$`009EndIf
X$`009If .not. Yes`009`009`009`009`009`009`009! Abort unless YES
X$`009Then`009Say Info, "Update aborted"
X$`009`009Goto GET_ACCESS_PORT_NAME
X$`009EndIf
X$`009Record`091 P_1, L_1 `093 := 'New_User`009`009`009`009`009! Update old r
Vecord
X$`009Write /Update ALF_FILE Record`009`009`009`009`009! Write new data to fi
Vle
X$`009Say Info, "Access port ", Access_Port_Name, " modified to user ", New_U
Vser
X$`009Goto GET_ACCESS_PORT_NAME`009`009`009`009`009! Round until end
X$!
X$!`009Add new record
X$!
X$ ADD_RECORD:
X$`009Record`091 P_0, L_0 `093 := 'Access_Port_Name`009`009`009`009! Set acce
Vss port name
X$`009Record`091 P_1, L_1 `093 := 'New_User`009`009`009`009`009! Enter user n
Vame
X$`009Write ALF_FILE Record`009`009`009`009`009`009! Add new record
X$`009Say Info, "Access port ", Access_Port_Name, " set to user ", New_User
X$`009Goto GET_ACCESS_PORT_NAME`009`009`009`009`009! Round until end
X$!
X$!`009Delete a record
X$!
X$ DELETE_RECORD:
X$`009Read /Index=0 /Key=&Access_Port_Name /Error=NOT_FOUND ALF_FILE Record
X$`009`009`009`009`009`009`009`009`009! Read record to delete
X$`009Old_User := 'F$Extract( P_1, L_1, Record )`009`009`009! Get old user na
Vme
X$`009Say Info, "Access port ", Access_Port_Name, " currently set to user ",
V Old_User
X$`009Ask "* Confirm deletion `091Yes/No`093 : " Yes`009`009`009! Confirm del
Vetion
X$`009If Yes .eqs. "?"
X$`009Then`009Type /NoPage SYS$INPUT
X
X`009Type "YES" to confirm the deletion, "NO" or RETURN to
X`009abort the deletion.
X
X$`009`009Goto DELETE_RECORD
X$`009EndIf
X$`009If .not. Yes`009`009`009`009`009`009`009! Abort unless YES
X$`009Then`009Say Info, "Delete aborted"
X$`009`009Goto GET_ACCESS_PORT_NAME
X$`009EndIf
X$`009Read /Index=0 /Key=&Access_Port_Name /Delete ALF_FILE Record
X$`009Say Info, "Access port ", Access_Port_Name, " record deleted"
X$`009Goto GET_ACCESS_PORT_NAME`009`009`009`009`009! Round until end
X$!
X$ NOT_FOUND:`009`009`009`009`009`009`009`009! Record not found
X$`009Say Warn, "Access port ", Access_Port_Name, " record does not exist"
X$`009Goto GET_ACCESS_PORT_NAME`009`009`009`009`009! Round until end
X$!
X$!`009List all controlled access ports
X$!
X$ DO_LIST:
X$`009Ask "* Username         : " User_Name`009`009`009`009! Get associated u
+-+-+-+-+-+-+-+-  END  OF PART 1 +-+-+-+-+-+-+-+-

