From:	CSBVAX::MRGATE!@KL.SRI.Com,@eureka.clemson.edu:WARNOCK@prism.clemson.edu@SMTP 10-AUG-1987 13:48
To:	EVERHART
Subj:	PASS source (part 1 of 1)

Received: from RELAY.CS.NET by KL.SRI.COM with TCP; Mon 10 Aug 87 06:20:19-PDT
Received: from eureka.clemson.edu by RELAY.CS.NET id aa22107; 10 Aug 87 9:11 EDT
Date: Mon, 10 Aug 87 09:05 EST
From: Todd Warnock <WARNOCK@prism.clemson.edu>
Subject: PASS source (part 1 of 1)
To: info-vax%sri-kl.ARPA@RELAY.CS.NET
X-VMS-To: IN%"info-vax@sri-kl.arpa",WARNOCK     

Rather than send to the many that have requested it individually, I've decided
to post this to the net.   For those that missed the previous discussion(s),
PASS is placed in SYLOGIN.COM and is run for all interactive sessions.  It
forces a user to change his/her password at login if it has expired, eliminating
the calls ("I forgot to reset my password before I logged out...")  It also
handles users who get as far as the SET PASSWORD prompt and then hang up (modem
users) or disconnect (lat users).  They are forced to changed the password 
when they login again.

Good luck with it.  As usual, I'm very interested in suggestions, improvements,
or comments about it !

Todd Warnock
VAX Systems
Clemson University
Clemson, South Carolina 29634-2803

ARPA:	Warnock@Prism.Clemson.EDU
BITnet:	Warnock@Clemson
CSnet:	Warnock@Clemson.CSnet

........................ Cut between dotted lines and save ......................
$!..............................................................................
$! VAX/VMS archive file created by VMS_SHAR V-4.03 05-Aug-1987
$! which was written by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au)
$! To unpack, simply save and execute (@) this file.
$!
$! This archive was created by WARNOCK
$!      on Monday 10-AUG-1987 08:58:00.99
$!
$! It contains the following 4 files:
$! PASS.FOR PASS.DOC UAIDEF.MAR SETPASS.COM
$!==============================================================================
$ Set Symbol/Scope=(NoLocal,NoGlobal)
$ Version=F$GetSYI("VERSION") ! See what VMS version we have here:
$ If Version.ges."V4.4" then goto Version_OK
$ Write SYS$Output "Sorry, you are running VMS ",Version, -
                ", but this procedure requires V4.4 or higher."
$ Exit 44
$Version_OK: CR[0,8]=13
$ Pass_or_Failed="failed!,passed."
$ Goto Start
$Convert_File:
$ Read/Time_Out=0/Error=No_Error1/Prompt="creating ''File_is'" SYS$Command ddd
$No_Error1: Define/User_Mode SYS$Output NL:
$ Edit/TPU/NoSection/NoDisplay/Command=SYS$Input/Output='File_is' -
        VMS_SHAR_DUMMY.DUMMY
f:=Get_Info(Command_Line,"File_Name");b:=Create_Buffer("",f);
o:=Get_Info(Command_Line,"Output_File");Set (Output_File,b,o);
Position (Beginning_of(b));Loop x:=Erase_Character(1); Loop ExitIf x<>"V";
Move_Vertical(1);x:=Erase_Character(1);Append_Line;Move_Horizontal
(-Current_Offset);EndLoop;Move_Vertical(1);ExitIf Mark(None)=End_of(b)
EndLoop;Exit;
$ Delete VMS_SHAR_DUMMY.DUMMY;*
$ Checksum 'File_is
$ Success=F$Element(Check_Sum_is.eq.CHECKSUM$CHECKSUM,",",Pass_or_Failed)+CR
$ Read/Time_Out=0/Error=No_Error2/Prompt=" CHECKSUM ''Success'" SYS$Command ddd
$No_Error2: Return
$Start:
$ File_is="PASS.FOR"
$ Check_Sum_is=844859990
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X	program PASS
X!+
X! Version:	1-001
X!
X! Facility:	System Management Library
X!
X! Abstract:	This module uses the system services $GETUAI and $SETUAI 
X!		to force users to change there password at login (assuming 
X!		it has expired).
X!
X! Environment:	User Mode, non-privileged
X!
X! Author:	Todd Warnock
X!		VAX Systems
X!		Clemson University
X!		Clemson, South Carolina 29634-2803
X!
X!		ARPA:	Warnock@Prism.Clemson.EDU
X!		BITnet:	Warnock@Clemson
X!		CSnet:	Warnock@Clemson.CSnet
X! Modified By:
X! 1-0001	- Original.  01-Jul-1986	RTW
X! 1-0002	- Modified   15-Jan-1987	RTW
X! 		  Modified to use $SETUAI to prevent dialup users
X!		  from hanging up during the set password part and 
X!		  being locked out of future logins. 
X!
X!-
X	implicit integer (a-z)
X	include '($rmsdef)'		
X	include '($ssdef)'		
X	include '($jpidef)'
Xc
Xc Since $UAFDEF is not in FORSYSDEF, it must be
Xc linked with PASS_UAIDEF and the symbols referenced as external.
Xc
X       	external uai$_flags	
X       	external uai$m_pwd_expired	
X       	external uai$v_pwd_expired	
Xc
Xc Setup names for LIB$DO_COMMAND
Xc (the logical name SYSUAF$CMD is defined to a command procedure
Xc to execute should the users password be marked as 'expired')
Xc
X        character*10 cmd_log_name /'SYSUAF$CMD'/
X        character*80 cmd_line 
Xc
X	character*12	username
X	integer		bit_value
X	integer		flags
X	integer		flags_len
X	logical		pwd_expired /.false./
Xc
Xc Define the variables for $GETJPI
Xc (Used to get the username for $GETUAI and $SETUAI)
Xc
X        character*12 jpi_username
X        integer*2    iosb(4)
X        integer*2    jpi_list(8) /12, JPI$_USERNAME, 6*0/
X        equivalence  (jpi_list(3), username_addr)
Xc
Xc SETUP the $GETUAI and $SETUAI item list
Xc (since both item lists are the same, define it only once)
Xc
X	structure/getuai_item/
X	union
X		map
X			integer*2	buffer_len
X			integer*2	item_code
X			integer*4	buffer_addr
X			integer*4	ret_len_addr
X		end map
X		map
X			integer*4	end_list/0/
X		end map
X	end union
X	end structure
X
X	record /getuai_item/ item_list(2)
Xc
Xc Define the item(s) (terminator is defined above)
Xc
X	item_list(1).item_code = %loc(uai$_flags)
X	item_list(1).buffer_len = 4
X	item_list(1).buffer_addr = %loc(flags)
X	item_list(1).ret_len_addr = %loc(flags_len)
Xc
Xc Get command line to reset password from SYSUAF$CMD by
Xc calling LIB$TRNLOG to translate logical name 
Xc
X        status=lib$sys_trnlog(cmd_log_name,,cmd_line,,,)
X	if (.not. status) call lib$stop (%val(status))
Xc
Xc Call $GETJPI (to get the username)
Xc
X        username_addr = %loc(jpi_username)
X        status=sys$getjpiw(%val(1),,,jpi_list,iosb,,)
X        if (.not. status) call lib$stop (%val(status))
X        if (.not. iosb(1)) call lib$stop (%val(iosb(1)))
X	username = jpi_username
Xc
Xc Call $GETUAI
Xc	
X	status = sys$getuai(,,%descr(username),
X     +		%ref(item_list),,,)
X	if (status .eq. rms$_rnf) then
X	  type*, 'USERID does not exist'
X	  call sys$exit(%val(status))
X	endif
X	if (.not.status) call lib$stop(%val(status))
Xc
Xc Call $SETUAI to reset PWD_EXPIRED flag
Xc (This is done so that, even though SETPASS.COM is protected so that
Xc  the used MUST change his password (he can't CTRL-Y out), if he is
Xc  dialed up, he can hangup, or if he's on the lat, he can break and
Xc  disconnect the session.  It also protects against a system crash
Xc  while reseting your password, leaving the UAF entry marked as
Xc  PWD_EXPIRED (thus disabling future logins)).
Xc
X	if (flags .eq. %loc(uai$m_pwd_expired)) then
X		pwd_expired = .true.
X		status = lib$bbcci(%loc(uai$v_pwd_expired),flags)
Xc		if (.not.status) call lib$stop(%val(status))
X		status = sys$setuai(,,%descr(username),
X     +			%ref(item_list),,,)
X		if (status .eq. rms$_rnf) then
X		  type*, 'USERID does not exist'
X		  call sys$exit(%val(status))
X		endif
Xc		if (.not.status) call lib$stop(%val(status))
X	endif
Xc
Xc Call LIB$DO_COMMAND to execute the command translated from
Xc the logical name SYSUAF$CMD
Xc
X	if (pwd_expired) then
X		status=lib$do_command(cmd_line)
X		if (.not. status) call lib$stop (%val(status))
X	endif 
X	end
$ GoSub Convert_File
$ File_is="PASS.DOC"
$ Check_Sum_is=621943604
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
XPASS - Forces users to change their password when it expires.
X
XCompilation:
X
XThe following steps are used to build PASS.EXE:
X
X	$ fortran 		pass
X	$ macro			uaidef
X	$ link/notraceback	pass,uaidef
X
XInstallation:
X
XThe following steps are used to install PASS in the SYS$COMMON:[SYSEXE]
Xdirectory (to make it accessible from all cluster nodes.)
XNote that pass is installed with SYSPRV in order for $SETUAI to work properly.
X
X	$install
X	add/open/head/share/priv=(sysprv) sys$common:[sysexe]pass.exe
X	exit
X	$copy/log pass.exe    sys$common:[sysexe]:pass.exe
X	$set prot=(w:e) sys$common:[sysexe]pass.exe
X	$copy/log setpass.com sys$common:[sysmgr]setpass.com
X	$define/system/exec     sysuaf$cmd	"@sys$manager:setpass"
X
XModify the system wide login command procedure to include this line FIRST:
X
X  $ if f$mode() .eqs. "INTERACTIVE" then run sys$system:pass
X
XThe image must be INSTALLed each time the system boots, so it should be
Xplaced in the system startup file for each cluster node.  
X
XNOTE:
X
XThis program is written is FORTRAN and is compatible with VMS 4.4 and above.
XIt will NOT work on VMS systems prior to VMS 4.4, since $GETUAI and $SETUAI
Xwere not available then.  Although it was designed to force users to change
Xtheir passwords, any action can be taken by modifying the command procedure
XSETPASS.COM. 
$ GoSub Convert_File
$ File_is="UAIDEF.MAR"
$ Check_Sum_is=102303317
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X	$UAIDEF	GLOBAL
X	.END
$ GoSub Convert_File
$ File_is="SETPASS.COM"
$ Check_Sum_is=679363608
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X$!*****
X$!*****	SETPASS.COM	invoked by the INSTALLed image SYS$SYSTEM:PASS.EXE
X$!*****
X$ SET NOON
X$ DEFINE/NOLOG SYS$INPUT TT
X$ ON CONTROL_Y THEN GOTO SET_PASS
X$SET_PASS:
X$ SET NOON
X$ ON ERROR THEN GOTO SET_PASS
X$ WRITE SYS$OUTPUT -
V "
You must change your password.  Now invoking SET PASSWORD for you...

$S
XET PASSWORD
"
X$ SET PASSWORD
X$ IF $STATUS THEN WRITE SYS$OUTPUT "Password change successful"
X$ EXIT
$ GoSub Convert_File
$ Exit
