;+
; 1.  Module name:  UPDATE_LOGIN_DATE
;
; 2.  File name:  LOGINDATE.MAR
;
; 3.  Purpose:
;
;	This program is intended to be invoked at login time by interactive
;	users.  It maintains a file containing seperate login information for
;	each system user.
;
;	The current login date/time and interactive terminal are recorded in the
;	file and the previous login date and terminal are returned to the
;	calling command procedure.
;
;	In addition, the recorded password is compared with the current
;	password from the UAF.  If they are different, the recorded password
;	is updated and the current date is stored as the password change date.
;
;	The number of days since the last password change is returned to the
;	calling command procedure.  If a new change date was just stored,
;	the number of days will be zero.
;
;	Note that the password obtained from the UAF is encoded and does not
;	compromise system security.
;
;	Note also, that the encoded password changes whenever the user's
;	password is updated, even if the password remains unchanged.  This
;	is because the encoding algorithm is time sensitive.  The UAF record
;	is tagged with 16 middle-order bits of the system time whenever the
;	password is changed.
;
; 4.  Author:
;
;	John Briggs
;	SPACECOM
;	1300 Quince Orchard Blvd.
;	Gaithersburg, MD  20878		(301) 258-6932
;
; 5.  Invocation Method:
;
;	$ RUN LOGINDATE
;
; 6.  Argument list:
;
;	Information is returned to the calling command procedure using
;	 CLI symbols.
;
;	PREVIOUS_DATE   : Previous login date in 11 character format (MM-DDD-YYYY)
;
;	PREVIOUS_MILTIM : Previous login time in 8 character format (HH:MM:SS)
;
;	PREVIOUS_TIME	: Previous login time in 11 character format (HH:MM:SS xm)
;
;	PASSWORD_AGE	: Number of days since password was changed
;
;	PREVIOUS_TERM	: Previous login terminal (6 characters)
;
; 7.  Error processing:
;
;	Regardless of what errors occur, the program will exit normally.  It
;	will not die with a cryptic traceback dump.
;
;	Normally, if an error occurs, the program will quietly abort.  The
;	output CLI symbols will be set to "ERROR".  Errors encountered in
;	setting the CLI symbols are ignored.
;
;	If $GETJPI does not return a terminal then this program is being
;	invoked as a batch job, sub-process or something.  The program
;	aborts quietly as above.
;
;	If the UAF cannot be read (probably because of insufficient privilege)
;	the password change date is left alone.  However, zero is returned
;	as PASSWORD_AGE.  Otherwise the program continues as if the read
;	had succeeded.
;
;	If the recording file cannot be updated, the program simply continues
;	as if it had been updated.
;
; 8.  File processing:
;
;	The system user authorization file (SYS$SYSTEM:SYSUAF.DAT) is read
;	 to determine the current user password (encoded).  The maximum
;	 possible file and record sharing are allowed.
;
;	The recording file (LOGINDATE_DIR:LOGINDATE.DAT) is read and updated.
;	 The maximum possible file and record sharing are allowed.  If the
;	 desired record is locked, the read will wait until it is unlocked
;	 but will time out if it is not unlocked within 5 seconds.
;	 If the record does not exist, one is created.
;
; 9.  Device processing:
;
;	None
;
; 10. Global storage references:
;
;	None
;
; 11. Internal tables and variables:
;
;	NAME		TYPE	DESCRIPTION
;
;	UAF_FAB		BLOCK	FAB for the system UAF (SYS$SYSTEM:SYSUAF.DAT)
;
;	UAF_RAB		BLOCK	RAB for the system UAF (SYS$SYSTEM:SYSUAF.DAT)
;
;	LOGFILE_FAB	BLOCK	FAB for the "log" file (LOGINDATE.DAT)
;
;	LOGFILE_XABKEY	BLOCK	Key definition XAB for the "log" file
;
;	LOGFILE_XABPRO	BLOCK	Protection definition XAB for the "log file
;
;	LOGFILE_RAB	BLOCK	RAB for the "log" file (LOGINDATE.DAT)
;
;	UAF_RECORD	BUFFER	Buffer for reading from the UAF
;	 UAF_USERNAME	C12	User name in the UAF buffer
;	 UAF_PASSWORD	I8	Quadword encoded password in the UAF buffer
;
;	LOG_RECORD	BUFFER	Buffer for use with the "log" file
;	 LOG_USERNAME	C12	User name in the log buffer
;	 LOG_LOGIN_TIME	I8	Quadword login date/time in the log buffer
;	 LOG_LOGIN_TERM	C6	Login terminal in the log buffer
;	 LOG_PASSWORD	I8	Quadword encoded password in the log buffer
;	 LOG_CHANGE_DATE
;			I8	Quadword passowrd change date/time in log buffer
;
;	ITEMLIST	BLOCK	Item list for use with $GETJPI
;
;	CLI_LOGIN_DATE	C11	String descriptor and string for login date as
;				 returned to the CLI
;	CLI_MIL_TIME	C11	String descriptor and string for military login
;				 time as returned to the CLI
;	CLI_STD_TIME	C11	String descriptor for standard time as returned
;				 to the CLI
;	STD_TIME_8	C8	String descriptor for standard time output from
;				 $ASCTIM
;	STD_TIME_T	C11	String space for CLI_STD_TIME and STD_TIME_8
;
;	CLI_PASSWORD_AGE_STRING String descriptor and string for password age
;			C12	 as returned to the CLI
;	CLI_LOGIN_TERM  C6	String descriptor for login terminal as returned
;				 to the CLI
;	CLI_NEVER	C5	"NEVER"
;	CLI_ZERO	C1	"0"
;	CLI_NONE	C4	"NONE"
;	CLI_ERROR	C5	"ERROR"
;	CLI_PREVIOUS_DATE
;			C13	"PREVIOUS_DATE"
;	CLI_PREVIOUS_MILTIM
;			C15	"PREVIOUS_MILTIM"
;	CLI_PREVIOUS_TIME
;			C13	"PREVIOUS_TIME"
;	CLI_PASSWORD_AGE
;			C12	"PASSWORD_AGE"
;	CLI_PREVIOUS_TERM
;			C13	"PREVIOUS_TERM"
;
;	CLI_FAO_ZL	C3	"!ZL" -- FAO control string for formatting
;				 password age
;
;	USERNAME	C12	User name as returned by $GETJPI and used
;				 as key into UAF
;	CURRENT_LOGIN_TIME	Quadword date/time of current login as returned
;			I8	 by $GETJPI
;	PREVIOUS_LOGIN_TIME	Quadword date/time of previous login.  Comes
;			I8	 from the log file.
;	LOGIN_TERM_LENGTH	Number of characters in the login terminal from
;			I2	$GETJPI
;	CURRENT_LOGIN_TERM	Login terminal from $GETJPI.  Trailing hex zero's
;			C6	 are replaced by blanks.
;	PREVIOUS_LOGIN_TERM	Previous login terminal retrieved from the log
;			C6	 file
;
;	PASSWORD_AGE	I4	Number of days since password was last changed
;	PASSWORD_AGE_Q	I8	Quadword interval since password was changed
;				 (in units of 100 nanoseconds)
;
;	TWELVE		C2	"12" (used in checking time for am/pm)
;
; 12. External module / macro references:
;
;	$ASCTIM_S		
;	$CONNECT
;	$CLOSE
;	$DISCONNECT
;	$FAO_S
;	$GET
;	$GETJPI_S
;	$OPEN
;	$PUT
;	$UPDATE
;
;	$FAB
;	$RAB
;	$XAB
;
;	LIB$DAY
;	LIB$SET_SYMBOL
;
; 13. Event flags:
;
;	None
;
; 14. Restrictions / warnings:
;
;	The recording file (and of course, the UAF) should be protected
;	 against all access by ordinary users.  Only system users should
;	 be allowed access to these files.  Since this image requires access
;	 it should be installed with privilege (SYSPRV).
;
;	Nothing will break if this program is not installed.  It will just
;	 return "ERROR" in its CLI symbols for all but system users.
;
; 15. Change History:
;
;	NAME		ORGANIZATION	DATE	DESCRIPTION
;
;	John Briggs	SPACECOM      15-NOV-83 Created
;
; 16. Program Design Language:
;
;	Determine the login time and terminal
;	IF there is no terminal THEN
;	    Exit
;	END IF
;
;	Open the UAF and read the current password
;	IF the UAF could not be read THEN
;	    Leave the password blank
;	END IF
;	Close the UAF
;
;	Open the recording file
;	Read the previous login time, terminal, password and change date
;	IF an error occurs THEN
;	    Exit
;	END IF
;
;	IF there is no record of the user THEN
;	    Create one with zero as password date and today as login date
;	    Use zero as the previous login date
;	    Use zero as the password change date
;	    Return "NEVER", "0" and "NONE" as CLI symbols.
;	ELSE
;	    IF the previous password is non-blank  AND
;	       the current password is different THEN
;		Update the recorded password and change date
;	    END IF
;	    Update the login time and terminal
;	    Return the login date, military time, regular time, password age and
;	     login terminal as CLI symbols
;	END IF
;	Close the recording file
;
;*****************************************************************************
;
; Source Code:
;
	.TITLE	UPDATE_LOGIN_DATE

	.MACRO	CHECK_STATUS	BRANCH,?LAB
	BLBS	R0,LAB
	.IF	NB	BRANCH
	 BRW	BRANCH
	.IF_FALSE
	 RET
	.ENDC
LAB:
	.ENDM


	.PSECT	DATA	WRT,NOEXE,NOSHR,PIC,REL,CON,LONG
;+
; FAB's and RAB's
;-
	.ALIGN	LONG
UAF_FAB:
	$FAB	FNM=<SYS$SYSTEM:SYSUAF.DAT>, -
		FAC=<GET>, -
		SHR=<GET,PUT,DEL,UPD>
UAF_RAB:
	$RAB	FAB=UAF_FAB, -
		ROP=<NLK,RRL>, -
		UBF=<UAF_RECORD>, -
		USZ=<20>, -
		RAC=KEY, -
		KRF=0, -
		KBF=USERNAME, -
		KSZ=12

LOGFILE_FAB:
	$FAB	FNM=<LOGINDATE_DIR:LOGINDATE.DAT>, -
		FAC=<GET,PUT,UPD>, -
		ALQ=48, -
		DEQ=48, -
		BKS=1, -
		FOP=<CBT,CIF>, -
		MRS=42, -
		ORG=IDX, -
		RAT=<CR>, -
		RFM=FIX, -
		SHR=<GET,PUT,DEL,UPD>, -
		XAB=LOGFILE_XABKEY
LOGFILE_XABKEY:
	$XABKEY	REF=0,POS=0,SIZ=12, -	; Key is first 12 characters
		NXT=LOGFILE_XABPRO
LOGFILE_XABPRO:				; Protection = S:RWED
	$XABPRO	PRO=<RWED,,,>
LOGFILE_RAB:
	$RAB	FAB=LOGFILE_FAB, -
		KRF=0, -
		KBF=USERNAME, -
		KSZ=12, -
		RAC=KEY, -
		RBF=<LOG_RECORD>, -
		ROP=<WAT,TMO>, -
		TMO=5, -
		RSZ=42, -
		UBF=<LOG_RECORD>, -
		USZ=42

;+
; Buffers
;-	
.ALIGN	LONG

UAF_RECORD:
UAF_USERNAME:
	.BLKB	12
UAF_PASSWORD:
	.BLKQ	1

LOG_RECORD:
LOG_USERNAME:
	.BLKB	12
LOG_LOGIN_TIME:
	.BLKQ	1
LOG_LOGIN_TERM:
	.BLKB	6
LOG_PASSWORD:
	.BLKQ	1
LOG_CHANGE_DATE:
	.BLKQ	1

;+
; Item list for $GETJPI
;-
ITEMLIST:
	.WORD	12
	.WORD	JPI$_USERNAME
	.ADDRESS -
		USERNAME
	.LONG	0
	.WORD	8
	.WORD	JPI$_LOGINTIM
	.ADDRESS -
		CURRENT_LOGIN_TIME
	.LONG	0
	.WORD	6
	.WORD	JPI$_TERMINAL
	.ADDRESS -
		CURRENT_LOGIN_TERM
	.ADDRESS -
		LOGIN_TERM_LENGTH
	.LONG	0

;+
; Data for return to the CLI
;-
CLI_LOGIN_DATE:
	.ASCID	/DD-MMM-YYYY/

CLI_MIL_TIME:
	.ASCID	/HH:MM:SS/

CLI_STD_TIME:
	.LONG	11
	.ADDRESS -
		STD_TIME_T
STD_TIME_8:
	.LONG	8
	.ADDRESS -
		STD_TIME_T
STD_TIME_T:
	.ASCII	/HH:MM:SS am/

CLI_PASSWORD_AGE_STRING:
	.ASCID	/000000000000/

CLI_LOGIN_TERM:
	.LONG	6
	.ADDRESS -
		PREVIOUS_LOGIN_TERM

CLI_NEVER:
	.ASCID	/NEVER/
CLI_ZERO:
	.ASCID	/0/
CLI_NONE:
	.ASCID	/NONE/
CLI_ERROR:
	.ASCID	/ERROR/

CLI_PREVIOUS_DATE:
	.ASCID	/PREVIOUS_DATE/
CLI_PREVIOUS_MILTIM:
	.ASCID	/PREVIOUS_MILTIM/
CLI_PREVIOUS_TIME:
	.ASCID	/PREVIOUS_TIME/
CLI_PASSWORD_AGE:
	.ASCID	/PASSWORD_AGE/
CLI_PREVIOUS_TERM:
	.ASCID	/PREVIOUS_TERM/

CLI_FAO_ZL:
	.ASCID	/!ZL/

;+
; Miscellaneous variables
;-
USERNAME:
	.BLKB	12

CURRENT_LOGIN_TIME:
	.BLKQ	1
PREVIOUS_LOGIN_TIME:
	.BLKQ	1

LOGIN_TERM_LENGTH:
	.WORD	0
CURRENT_LOGIN_TERM:
	.BLKB	6
PREVIOUS_LOGIN_TERM:
	.BLKB	6

PASSWORD_AGE:
	.BLKL	1
PASSWORD_AGE_Q:
	.BLKQ	1

TWELVE:	.ASCII	/12/

	.PSECT	CODE	NOWRT,EXE,SHR,PIC,REL,CON
	.ENTRY	UPDATE_LOGIN_DATE,^M<R2,R3,R4,R5>

	CLRQ	UAF_PASSWORD		; Clear default password
;+
; Determine the user name, login time and terminal
;-
	$GETJPI_S -			; Get username, login time and terminal
		ITMLST=ITEMLIST
	CHECK_STATUS -			; On error exit indicating failure
		BRANCH=ERROR_EXIT
	MOVC5	LOGIN_TERM_LENGTH, -	; Pad terminal with blanks
		CURRENT_LOGIN_TERM, -
		#32, -
		#6, -
		CURRENT_LOGIN_TERM
	CMPC5	#6, -			; Check for blank terminal -- terminal
		CURRENT_LOGIN_TERM, -	;  will be blank for batch jobs,
		#32, -			;  sub-processes, etc.
		#0, -
		#0
	BNEQ	CHECK_UAF
	BRW	ERROR_EXIT		; If blank exit indicating failure
;+
; Determine the current password as stored in the UAF
; (It is stored as a coded quadword field)
; If the password cannot be determined, leave it as zero
;-
CHECK_UAF:
	$OPEN	FAB=UAF_FAB		; Open the UAF with maximum file sharing
	CHECK_STATUS -			; If the open or connect fails,
		BRANCH=20$		;  treat as blank password.
	$CONNECT -
		RAB=UAF_RAB
	CHECK_STATUS -
		BRANCH=10$
	$GET	RAB=UAF_RAB		; Get the coded password for the user
	$DISCONNECT -			; Close the UAF
		RAB=UAF_RAB
10$:	$CLOSE	FAB=UAF_FAB
20$:
;+
; Get recorded information about last login from the "log" file
;-
CHECK_LOGFILE:
	$CREATE	FAB=LOGFILE_FAB		; Open the file containing login data
	CHECK_STATUS -			; On error, exit indicating failure
		BRANCH=ERROR_EXIT
	$CONNECT -
		RAB=LOGFILE_RAB
	CHECK_STATUS -
		BRANCH=CLOSE_ERROR_EXIT
	$GET	RAB=LOGFILE_RAB		; Read login data for the user
	CMPL	R0,#RMS$_RNF		; If the user doesn't have a record
	BEQL	FIRST_LOGIN		;  create one for him
	CHECK_STATUS -			; If the read fails otherwise, exit
		BRANCH=DISC_ERROR_EXIT	;  indicating failure
	BRW	NORMAL_LOGIN
;+
; No record exists in the "log" file for this user --
; First, create a new record, then set up the CLI symbols to indicate a new user
;-
FIRST_LOGIN:
	MOVC3	#12,USERNAME, -		; Copy the username into the log record
		LOG_USERNAME
	MOVQ	CURRENT_LOGIN_TIME, -	; Copy login time into the log record
		LOG_LOGIN_TIME
	MOVC3	#6,CURRENT_LOGIN_TERM, -; Copy login terminal into the log rec.
		LOG_LOGIN_TERM
	MOVQ	UAF_PASSWORD, -		; Copy coded password into the log rec.
		LOG_PASSWORD
	CLRQ	LOG_CHANGE_DATE		; The password change date can be stored
;	MOVQ	CURRENT_LOGIN_TIME, -	; either as zero (Nov 18, 1858) or as
;		LOG_CHANGE_DATE		; the date of the current login.
	MOVW	LOGFILE_RAB+RAB$W_USZ, -; Write the new record to the file
		LOGFILE_RAB+RAB$W_RSZ

	$PUT	RAB=LOGFILE_RAB
	PUSHAL	CLI_NEVER		; Return "NEVER" as PREVIOUS_DATE
	PUSHAL	CLI_PREVIOUS_DATE
	CALLS	#2,G^LIB$SET_SYMBOL
	PUSHAL	CLI_NEVER		; Return "NEVER" as PREVIOUS_MILTIM
	PUSHAL	CLI_PREVIOUS_MILTIM
	CALLS	#2,G^LIB$SET_SYMBOL
	PUSHAL	CLI_NEVER		; Return "NEVER" as PREVIOUS_TIME
	PUSHAL	CLI_PREVIOUS_TIME
	CALLS	#2,G^LIB$SET_SYMBOL
	PUSHAL	CLI_ZERO		; Return "0" as PASSWORD_AGE
	PUSHAL	CLI_PASSWORD_AGE
	CALLS	#2,G^LIB$SET_SYMBOL
	PUSHAL	CLI_NONE		; Return "NONE" as PREVIOUS_TERM
	PUSHAL	CLI_PREVIOUS_TERM
	CALLS	#2,G^LIB$SET_SYMBOL
	BRW	CLOSE_LOGFILE		; Close the log file
;+
; A record exists for this user in the "log" file -- Update it
; If the current password (from the UAF) is different from the old password
;  (from the log file) then update the password change date.
;-
NORMAL_LOGIN:
	MOVQ	LOG_LOGIN_TIME, -	; Save previous login time
		PREVIOUS_LOGIN_TIME
	MOVC3	#6,LOG_LOGIN_TERM, -	; Save previous login terminal
		PREVIOUS_LOGIN_TERM
	MOVQ	CURRENT_LOGIN_TIME, -	; Copy login time into the log record
		LOG_LOGIN_TIME
	MOVC3	#6,CURRENT_LOGIN_TERM, -; Copy login terminal into the log rec.
		LOG_LOGIN_TERM
	CMPC3	#8,UAF_PASSWORD, -	; Has the password been changed?
		LOG_PASSWORD
	BEQL	10$
	CMPC5	#8,UAF_PASSWORD, -	; Is the new one non-zero?
		#0,#0,#0
	BEQL	10$
	MOVQ	CURRENT_LOGIN_TIME, -	; If the password is non-zero and has
		LOG_CHANGE_DATE		;  been changed, update the change date
	MOVQ	UAF_PASSWORD, -		;  and coded password in the log file.
		LOG_PASSWORD
10$:	$UPDATE	RAB=LOGFILE_RAB		; Update the user's record on disk
;+
; Create CLI symbols for previous login date/time/terminal and password age
;-

	$ASCTIM_S -			; Decode previous login as ASCII date
		TIMBUF=CLI_LOGIN_DATE -
		TIMADR=PREVIOUS_LOGIN_TIME -
		CVTFLG=#0
	PUSHAL	CLI_LOGIN_DATE		; Return date as PREVIOUS_DATE
	PUSHAL	CLI_PREVIOUS_DATE
	CALLS	#2,G^LIB$SET_SYMBOL
	$ASCTIM_S -			; Decode previous login as military
		TIMBUF=CLI_MIL_TIME -	;  time
		TIMADR=PREVIOUS_LOGIN_TIME -
		CVTFLG=#1
	PUSHAL	CLI_MIL_TIME		; Return military time as PREVIOUS_MILTIM
	PUSHAL	CLI_PREVIOUS_MILTIM
	CALLS	#2,G^LIB$SET_SYMBOL
	CMPC3	#2,@CLI_MIL_TIME+4, -	; Check hour for am/pm
		TWELVE
	BGEQ	20$
	MOVB	#^A/a/,STD_TIME_T+9	; It is am -- put in an "a"
	MOVC3	#8,@CLI_MIL_TIME+4, -	; Copy military time to standard string
		STD_TIME_T
	BRB	30$			; Check for midnite
20$:	MOVB	#^A/p/,STD_TIME_T+9	; It is pm -- put in a "p"
	SUBL2	#^X9534E000, -		; Subtract 12 hours from login time
		PREVIOUS_LOGIN_TIME
	SBWC	#^X64, -
		PREVIOUS_LOGIN_TIME+4
	$ASCTIM_S -			; Re-convert time in standard form
		TIMBUF=STD_TIME_8 -
		TIMADR=PREVIOUS_LOGIN_TIME -
		CVTFLG=#1
30$:	CMPW	STD_TIME_T,#^A/00/	; Is the hour "00"?
	BNEQ	40$			; No -- leave it alone
	MOVW	#^A/12/,STD_TIME_T	; Yes -- change it to noon (or midnite)
40$:	CMPB	STD_TIME_T,#^A/0/	; Is the first character "0"?
	BNEQ	50$			; No -- leave it alone
	DECW	CLI_STD_TIME		; Yes -- remove first character
	INCL	CLI_STD_TIME+4
50$:	PUSHAL	CLI_STD_TIME		; Return standard time as PREVIOUS_TIME
	PUSHAL	CLI_PREVIOUS_TIME
	CALLS	#2,G^LIB$SET_SYMBOL
	MOVQ	CURRENT_LOGIN_TIME, -	; Subtract password change date from
		PASSWORD_AGE_Q		;  login time giving password age in
	SUBL2	LOG_CHANGE_DATE, -	;  hundreds of nano-seconds.
		PASSWORD_AGE_Q
	SBWC	LOG_CHANGE_DATE+4, -
		PASSWORD_AGE_Q+4
	PUSHAQ	PASSWORD_AGE_Q		; Convert hundreds of nano-seconds to
	PUSHAL	PASSWORD_AGE		;  days
	CALLS	#2,G^LIB$DAY
	BLBS	R0,60$			; If conversion fails, use zero
	CLRL	PASSWORD_AGE
60$:	$FAO_S	CTRSTR=CLI_FAO_ZL, -	; Convert password age to ASCII text
		OUTBUF=CLI_PASSWORD_AGE_STRING, -
	        OUTLEN=CLI_PASSWORD_AGE_STRING, -
		P1=PASSWORD_AGE
	PUSHAL	CLI_PASSWORD_AGE_STRING	; Return age in days as PASSWORD_AGE
	PUSHAL	CLI_PASSWORD_AGE
	CALLS	#2,G^LIB$SET_SYMBOL
	PUSHAL	CLI_LOGIN_TERM		; Return previous login terminal (from
	PUSHAL	CLI_PREVIOUS_TERM	;  the log file) as PREVIOUS_TERM
	CALLS	#2,G^LIB$SET_SYMBOL
;+
; Close the "log" file and exit
;-
CLOSE_LOGFILE:
	$DISCONNECT -			; Close the file of login data
		RAB=LOGFILE_RAB
	$CLOSE	FAB=LOGFILE_FAB
	MOVL	#SS$_NORMAL,R0		; EXIT normally
	RET
;+
; An error has occurred which prevents normal operation --
; Set all CLI symbols to "ERROR" and exit
;-
DISC_ERROR_EXIT:
	$DISCONNECT -			; Close the "log" file
		RAB=LOGFILE_RAB
CLOSE_ERROR_EXIT:
	$CLOSE	FAB=LOGFILE_FAB
ERROR_EXIT:
	PUSHAL	CLI_ERROR		; Return "ERROR" as PREVIOUS_DATE
	PUSHAL	CLI_PREVIOUS_DATE
	CALLS	#2,G^LIB$SET_SYMBOL
	PUSHAL	CLI_ERROR		; Return "ERROR" as PREVIOUS_MILTIM
	PUSHAL	CLI_PREVIOUS_MILTIM
	CALLS	#2,G^LIB$SET_SYMBOL
	PUSHAL	CLI_ERROR		; Return "ERROR" as PREVIOUS_TIME
	PUSHAL	CLI_PREVIOUS_TIME
	CALLS	#2,G^LIB$SET_SYMBOL
	PUSHAL	CLI_ERROR		; Return "ERROR" as PASSWORD_AGE
	PUSHAL	CLI_PASSWORD_AGE
	CALLS	#2,G^LIB$SET_SYMBOL
	PUSHAL	CLI_ERROR		; Return "ERROR" as PREVIOUS_TERM
	PUSHAL	CLI_PREVIOUS_TERM
	CALLS	#2,G^LIB$SET_SYMBOL
	MOVL	#SS$_NORMAL,R0		; EXIT normally
	RET
	.END	UPDATE_LOGIN_DATE
