From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX"  7-JUN-1989 18:43
To:	MRGATE::"ARISIA::EVERHART"
Subj:	Re: Change username

Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Wed,  7 JUN 89 13:30:47 PDT
Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Wed, 7 Jun 89 13:05:21 PDT
Received: by ucbvax.Berkeley.EDU (5.61/1.36)
	id AA08277; Wed, 7 Jun 89 12:56:07 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 7 Jun 89 19:05:46 GMT
From: blake!ingersol@beaver.cs.washington.edu  (Steve Ingersoll)
Organization: University of Washington, Seattle
Subject: Re: Change username
Message-Id: <2332@blake.acs.washington.edu>
References: <398@uncw.UUCP>, <16317@hc.DSPO.GOV>, <402@uncw.UUCP>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com


	The following is the macro source code for a program to become
somebody else. To compile the program you must type:

	$ MACRO BE.MAR+SYS$LIBRARY:LIB/LIBRARY

	And to link

	$ LINK BE,SYS$SYSTEM:SYS.STB/SELECTIVE

	Once the program is compiled and link you can specify a foreign
command line for the program ( but it is not necessary ).

	$ BE :== $sys$disk:[directory]BE


----------------------------------------------------------------------------
		.title BE * Be somebody else *
;
;		This program changes the following values in the current
;	process's PCB:
;
;		o username
;		o UIC
;		o process name
;		o priviledge mask 
;		o definition of SYS$LOGIN
;
;	To match that of the user specified in the foriegn command line as
;	defined in the SYSUAF.DAT file.
;
;	Author: John Weber
;	Date: August 12, 1983
;
;	Modification History:
;
		.page
		.subtitle * Symbol definitions *

		$JIBDEF			;JIB offsets
		$PCBDEF			;PCB offset definitions
		$UAFDEF			;UAF record offsets

	.MACRO	check_error string,?label
	blbs	R0,label
	.if	not_blank,<string>
	    pushl R0
	    term_message <string>
	    popl R0
	.endc
	$exit_s	R0
label:
	.ENDM


		.macro	term_message string,?label
		.save_psect local_block
		.psect	strings noexe,nowrt,rd
label:		.ascid	/string/
		carry_over=label
		.restore_psect
		pushr	#^M<R0,R1>
		pushaq	carry_over
		calls	#1,G^lib$put_output
		popr	#^M<R0,R1>
		.endm

		.page 
		.subtitle * Read-only data *

		.psect	ro_data,rd,nowrt,noexe

no_input_prompt:.ascid	/_Username: /
login_ctrstr:	.ascid	/!AC!AC/
login_logical:	.ascid	/SYS$LOGIN/

		.page
		.subtitle * Read-write data *

		.psect	rw_data,rd,wrt,noexe
;
;		RMS FAB definition for UAF file...
;
uaf_fab:	$fab	fac = get,-
			fnm = <sys$system:sysuaf.dat>,-
			shr = <get,put,del,upd>,-
			org = idx,-
			rfm = var,-
			mrs = uaf$c_length
;
;		RMS RAB definition for UAF file...
;
uaf_rab:	$rab	rop = rlk,-
			rac = key,-
			krf = 0,-
			kbf = <uaf_record+uaf$t_username>,-
			ksz = uaf$s_username,-
			ubf = uaf_record,-
			usz = uaf$c_length,-
			fab = uaf_fab

change_log_fab:	$fab	fnm=<SYS$ERRORLOG:CHANGE.LOG>, -
			mrs=2*uaf$s_username+23, -
			rat=<CR>, -
			rfm=fix, -
			org=seq, -
			fac=<PUT>, -
			fop=<CIF>
change_log_rab:	$rab	fab=change_log_fab, -
			rac=seq, -
			rbf=change_record, -
			rsz=2*uaf$s_username+23, -
			rop=<EOF>

ascii_time_desc:
		.word	23
		.byte	DSC$K_DTYPE_T,DSC$K_CLASS_S
 		.address -
			ascii_time

;
;	The next two lines must remain together because both are written
;	to the log file.
;
change_record:	.blkb	2*uaf$s_username
ascii_time:	.blkb	23

input_desc:	.word	0			;Dynamic string desc for input
		.byte	DSC$K_DTYPE_T,DSC$K_CLASS_D
		.long	0

uaf_record:	.blkb	uaf$c_length

un_desc:	.word	12
		.byte	DSC$K_DTYPE_T,DSC$K_CLASS_S
		.address -
			uaf_record+uaf$t_username

getjpi_list:	.word	7		;GETJPI list to get terminal...
		.word	jpi$_terminal
		.address term_buffer
		.address term_desc
		.word	uaf$s_username
		.word	jpi$_username
		.address oldusername
		.address oldusernamelen
		.long	0

term_desc:	.word	7
		.byte	DSC$K_DTYPE_T,DSC$K_CLASS_S
		.address -
			term_buffer
term_buffer:	.blkb	7

oldusernamelen:	.word	0
oldusername:	.blkb	uaf$s_username

login_directory:.word	50		;String desc for default directory
		.byte	DSC$K_DTYPE_T,DSC$K_CLASS_S
		.address -
			login_dir_buff
login_dir_buff:	.blkb	50

		.page
		.subtitle * Routine startup *

		.psect	code,rd,nowrt,exe
		
		.entry	be,^M<>
;
;		Read foreign command line, prompt if not specified.
;
		pushaq	no_input_prompt
		pushaq	input_desc
		calls	#2,G^lib$get_foreign
		check_error <Can't get foriegn command line>
;
;		Try to open and connect to the LOG file
;
		$create	fab=change_log_fab	; Create ( or OPEN ) log file
		check_error <Error>		; If error die...
		$connect rab=change_log_rab	; Connect to the log file
		check_error <Error>
;
;		Get the current process name and terminal
;
		$getjpi_s	itmlst=getjpi_list
		check_error <Can't get process's terminal>

;
;		Fill in the log file data
;
		movc5	oldusernamelen,oldusername,#^A/ /, -
			#uaf$s_username,change_record

		movc5	input_desc,@input_desc+4,#^A/ /,-
			#uaf$s_username,change_record+uaf$s_username

		$asctim_s -
			timbuf=ascii_time_desc

;
;		Now write the log record
;
		$put	rab=change_log_rab
		check_error <Error...>

;
;		Close the log file
;
		$close	fab=change_log_fab
		check_error <Error...>

;
;		Try to open and connect to the UAF file
;
		$open	fab=uaf_fab
		check_error <Can't open UAF file....>
		$connect rab=uaf_rab
		check_error <Can't $CONNECT UAF file...>
;
;		Try to read the record that has a key value equal to the
;		specified username.
;
		movc5	input_desc,@input_desc+4,#32,-
			#uaf$s_username,uaf_record+uaf$t_username
		$get	rab=uaf_rab
		check_error <Can't read UAF record>
		$close	fab=uaf_fab
		check_error <Error closing UAF file>
;
;		Got the record, now execute kernel mode routine to move all
;	relevent information into our PCB and JIB.
;
		$cmkrnl_s	routin=change_pcb
		check_error <Can't change process information>
;
;		Try to change the process name to the current username. If
;	a process already exists with that name, use the current terminal
;	designator as the process name.
;

    		$setprn_s	prcnam=un_desc
		cmpl	#ss$_duplnam,R0
		beql	10$
		check_error <Can't set process name...>
		brb	20$

10$:		$setprn_s	prcnam=term_desc
		check_error <Can't set process name....>
;
;		Redefine process logical for SYS$LOGIN...
;
20$:		$fao_s		ctrstr=login_ctrstr,-
				outlen=login_directory,-
				outbuf=login_directory,-
				P1=#uaf_record+uaf$t_defdev,-
				P2=#uaf_record+uaf$t_defdir
		check_error <Error creating default directory string>
;
;		Change mode to EXEC so we can redefine the SYS$LOGIN
;	logical name.
;
		$cmexec_s	routin=set_logical
		check_error <Can't define logical for SYS$LOGIN>

		$exit_s

		.page
		.subtitle * Change PCB fields *
;
;		Here's where we change any necessary information in the PCB 
;	and JIB to make ourselves look like somebody else.
;
		.entry	change_pcb,^M<R2,R3,R4,R5,R6,R7>

		movl	ctl$gl_pcb,R6			;Current PCB address
		movl	pcb$l_jib(R6),R7		;Current JIB address
		movc	#uaf$s_username,-		;Copy username to JIB
			uaf_record+uaf$t_username,jib$t_username(R7)
		movc	#uaf$s_username,-		;And control region
			uaf_record+uaf$t_username,@#ctl$t_username
		movl	uaf_record+uaf$l_uic,pcb$l_uic(R6) ;Set new UIC in PCB
;		movl	uaf_record+uaf$l_uic,jib$l_uic(R7) ; and JIB
		movq	uaf_record+uaf$q_priv,pcb$q_priv(R6) ;Change priv mask
;		movq	uaf_record+uaf$q_priv,jib$q_priv(R7) ; in PCB and JIB

		movl	#ss$_normal,R0			;Return OK...
		ret
;
;		This routine is executed in EXEC mode so we may redefine the
;	logical name of SYS$LOGIN.
;
		.entry	set_logical,^M<>

		$crelog_s	tblflg=#2,-
				lognam=login_logical,-
				eqlnam=login_directory
		ret

		.end BE
--------------------------------------------------------------------------------

Steve Ingersoll
ingersoll@vaxman.fmo.washington.edu
University of Washington
206 543-8200

