d 	.TITLE NEW Users Camelian Utility (Temporary Form)
 	.SBTTL Documentation
,;++
;
;  TITLE:  NEW.MAR
X;
;  FACILITY:  Users change to someone else system utility.
 ;
;  ABSTRACT:
;	This program allows a user who has the proper privilege to
L;	change some of his process context information to that of
;	some other user known to the system via SYS$SYSTEM:SYSUAF.DAT.
;
x;  ENVIRONMENT:
;	Runs as an image in the context of a process.  May signal
@;	any known SS$_ or RMS$_ return status.
;
;  AUTHOR: Ralph Weber		CREATION DATE: 27-FEB-1980
l;
;  MODIFIED BY:
4;	Ralph Weber 27-FEB-1980 modified FOR.MAR to create this program.
;
;---

d ;+++
 ;
,;  FUNCTIONAL DESCRIPTION:
;	After determining that the current process has at least GROUP
;	privilege this image determines the USERNAME to which portions
X;	of the process context are to be switched.  If no USERNAME was
;	given on the command line which invoked this image a USERNAME
 ;	is prompted for.  Then the system authorization file,
;	SYS$SYSTEM:SYSUAF.DAT is searched for the specified USERNAME.
;	If the USERNAME is found it's UIC is compared to the current
L;	UIC.  If the UIC groups do not match then the process must have
;	PHY_IO privilege to change to a system UIC or WORLD privilege
;	to change to a non-system UIC.  If the process lacks the needed
x;	privilege SS$_NOPRIV is returned as an exit status.  If the
;	process has the needed privilege the following elements of the
@;	software process context are atered based on the contents of
;	the SYSUAF entry found:
;	  PCB$L_UIC is set equal to UAF$L_UIC.
l;	  The device shown in UAF$T_DEFDEV is assigned to SYS$DISK.
;	  The RMS default directory is set from UAF$T_DEFDIR.
4;
;	If the USERNAME is not found or if the process invoking this
;	image lacks the privilege to effect the group to which it is
`	;	attempting to change (GROUP, WORLD, or PHY_IO privileges),
	;	no changes are made and the image exits with an error status.
(
;

;

;  CALLING SEQUENCE:
T;
;	$NEW:=$DRA0:[CYCEXE]NEW
;	$NEW Username
;
;
H;  INPUT PARAMETERS:
;
;	Username	is a USERNAME listed in SYS$SYSTEM:SYSUAF.DAT.
t;			If successful the process UIC, Default Device,
;			and Default Directory will be altered based
<;			on those belonging to Username.
;
;
h;  OUTPUT PARAMETERS:  None.
;
0;
;  IMPLICIT INPUTS:
;
\;	PCB$L_UIC	is the current UIC for this process.  It is
;			used to determine if running NEW is legal.
$;
;	SYS$SYSTEM:SYSUAF.DAT is the current system authorization file.
;			It is used to determine the new values for
P;			process context parameters altered by NEW.
;			This file is not altered!
;
|;
;  IMPLICIT OUTPUTS:
D;
;	PCB$L_UIC	changed to UAF$L_UIC.
;
p;	SYS$DISK	changed to UAF$T_DEFDEV.
;
8;	Default Directory changed to UAF$T_DEFDIR.
;
 ;
d;  SIDE EFFECTS:
;
,;	This image requires CMKRNL, CMEXEC, PHY_IO, and SYSNAM
;	privileges.
;
X;
;  COMPLETION STATUS:
 ;
;	SS$_NORMAL	if successful.
;	SS$_NOPRIV	if GROUP or WORLD or PHY_IO privilege is
L;			required to make a change but the process lack
;			the required privilege.
;	RMS$_EOF	if USERNAME not found in SYS$SYSTEM:SYSUAF.DAT.
x;	SS$_???? or RMS$_??? if other abnormal condition encountered.

d 		.SBTTL System Data Structures Definations
 
,	.LIBRARY /SYS$LIBRARY:LIB/

	$SSDEF		;SS$_ return status codes.
X	$JPIDEF		;SYS$GETJPI request codes.
	$PRVDEF		;User privileges bits definations
 	$PSLDEF		;Processor Status Longword definations.
	$LOGDEF		;Logical name table definations.
	$UAFDEF		;User Authorization File record offsets.
L	$PCBDEF		;Process Control Block offsets.


x;  PROGRAM PARAMETERS:

@
	.PSECT NEW_DATA, PIC,USR,CON,REL,LCL,NOSHR,NOEXE,RD,WRT,LONG

l
;  Data Structures Used for SYS$GETJPI
4
JPI_GET:
	.WORD 2, JPI$_GRP	;Get current group.
`		.LONG CURRENT_GROUP, 0
		.WORD 8, JPI$_PROCPRIV	;Get default process privileges.
(
	.LONG DEFAULT_PRIVS, 0

	.LONG 0			;List terminator.


TCURRENT_GROUP:
	.WORD 0
DEFAULT_PRIVS:
	.QUAD 0

H
;  Data Structures Used for CLI call back

t
GET_COMMAND:
<	$CLIREQDESC	-
		RQTYPE=CLI$K_GETCMD

h
;  Information Used to Prompt for Username
0
USRNM_PMT_DESC:
	.ASCID /Username: /
\USRNM_BUF_DESC:
	.LONG 9, NEW_USERNAME
$

;  Data Structures Used Accessing SYS$SYSTEM:SYSUAF.DAT
P
	.ALIGN	LONG

|SYSUAF_FAB:
	$FAB	FNM=<SYS$SYSTEM:SYSUAF.DAT>, -
D		FAC=GET, FOP=SQO

SYSUAF_RAB:
p	$RAB	FAB=SYSUAF_FAB, MBF=3, RAC=SEQ -
		ROP=RAH, UBF=UAF_RECORD, USZ=UAF$K_LENGTH
8
UAF_RECORD:
 	.BLKB UAF$K_LENGTH
d
UAF_ERROR_TEXT:
,	.ASCID /Error reading SYSUAF.DAT/


X;  USERNAME Buffer and Work Space

 NEW_USERNAME:
	.BLKB 12

L
;  Character Descriptors for Various Change-it System Calls

x	.ALIGN LONG

@NEW_DEVICE:
	.LONG 0, UAF_RECORD+UAF$T_DEFDEV+1
 
l SYS$DISK_NAME:
 	.ASCID /SYS$DISK/
4!
!	.ALIGN LONG
!
`"NEW_DIRECTORY:
"	.LONG 0, UAF_RECORD+UAF$T_DEFDIR+1
(#
#NEW_PRC_NAME:
#	.LONG 12, NEW_USERNAME

d 	.SBTTL Setup
 ;+++
,;  SETUP:
;	If caller lacks GROUP privilege don't even try to run.
;	Use CLI callback to obtain command line with desired new
X;	  USERNAME.
;	If USERNAME not present, prompt for USERNAME.
 ;	Open SYS$SYSTEM:SYSUAF.DAT and look for USERNAME.
;	If any errors regarding SYSUAF occur, exit giving message
;	  and RMS exit status.
L;	Close SYS$SYSTEM:SYSUAF.DAT.
;
;---
x

@	.PSECT NEW_CODE, PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT,LONG


l; NEW Program Entry Point
NEW_START:
4	.WORD	^M<R2,R3,R4,R5,R6,R7>


`	GET_PROC_INFO:
		$GETJPI_S ITMLST=JPI_GET	;Get default process privileges
(
	BLBS	R0, TEST_GROUP_PRIV	;and UIC group.

	$EXIT_S R0


TTEST_GROUP_PRIV:
	BBS	#PRV$V_GROUP, DEFAULT_PRIVS, - ;If no GROUP privilege
		100$			;don't even try to run.
	$EXIT_S	#SS$_NOPRIV
100$:
H

GET_NEW_USERNAM:
t	PUSHAB	GET_COMMAND		;Use CLI callback to get
	CALLS	#1, G^SYS$CLI		;invoking command parameter(s).
<	MOVQ	GET_COMMAND+CLI$Q_RQDESC, -  ;Move resultant string
		R6			;descriptor in R6 & R7.
	MOVC5	R6, (R7), #^A/ /,  -	;Move desired new USERNAME to
h		#12, NEW_USERNAME	;local working buffer.

0CHECK_NO_NAME:
	SKPC	#^A/ /, #9, NEW_USERNAME ;If no USERNAME is present,
	BNEQ	10$			;we must prompt for one.
\	PUSHAQ	USRNM_PMT_DESC
	PUSHAQ	USRNM_BUF_DESC
$	CALLS	#2, LIB$GET_COMMAND
	BLBS	R0, 10$
	$EXIT_S	R0
P10$:

OPEN_SYSUAF:
|	MOVAB	UAF_RECORD, R6		;Setup pointer to UAF input.
	$OPEN	FAB=SYSUAF_FAB		;Open SYS$SYSTEM:SYSUAF.DAT and
D	BLBC	R0, SYSUAF_ERROR	;prepair to process the file.
	$CONNECT RAB=SYSUAF_RAB
	BLBS	R0, SYSUAF_LOOP
p
SYSUAF_ERROR:
8	MOVL	R0, R2			;For any error on SYSUAF, give
	$CLOSE	FAB=SYSUAF_FAB		;a message stating that SYSUAF
 	PUSHAQ	UAF_ERROR_TEXT		;produced the error and exit
d	CALLS	#1, LIB$PUT_OUTPUT	;with error status as return
	$EXIT_S	R2			;status.
,

SYSUAF_LOOP:
X
	$GET	RAB=SYSUAF_RAB		;Read a UAF record.
 	BLBC	R0, SYSUAF_ERROR

	CMPC3	#12, NEW_USERNAME,  -	;Compare desired USERNAME
L		UAF$T_USERNAME(R6)	;with UAF USERNAME and when
	BNEQ	SYSUAF_LOOP		;they don't match try again.

x
FOUND_USERNAME:
@	$CLOSE	FAB=SYSUAF_FAB		;Close SYS$SYSTEM:SYSUAF.DAT.

d 	.SBTTL Action
 ;+++
,;
;  ACTION:
;	Proceed if:
X;		1) UIC groups match.
;		2) New UIC is not a system UIC and user has WORLD
 ;		   privilege.
;		3) New UIC is a system UIC and user has PHY_IO
;		   privilege.
L;	In KERNEL mode set PCB$L_UIC and use SYS$CRELOG to replace
;		SYS$DISK contents.
;	Use SYS$SETDIR to replace default directory.
x;---

@TEST_DEST_UIC:
	CMPW	CURRENT_GROUP, -	;If current group matches
		UAF$W_GRP(R6)		;desired new group,
l	BEQL	DO_IT			;go make changes.

4	CMPW	UAF$W_GRP(R6), -	;If desired new UIC is
		G^EXE$GL_SYSUIC		;not a system UIC,
	BLEQ	10$			;the user must have
`		BBS	#PRV$V_WORLD, DEFAULT_PRIVS, - ;WORLD privilege.
			DO_IT			;If it is a system UIC, he
(
10$:	BBS	#PRV$V_PHY_IO, DEFAULT_PRIVS, - ;must have PHY_IO

		DO_IT			;privilege.

	$EXIT_S	#SS$_NOPRIV		;Exit if insufficient privleges.
T
DO_IT:
KERNEL_ACTION:
	$CMKRNL_S ROUTIN=KRNL_ROUTINE
	BRB	GENERAL_ACTION
H
KRNL_ROUTINE:
	.WORD	^M<R2,R3,R4,R5,R6>
t	MOVAB	UAF_RECORD, R6		;Restore UAF record pointer.

<	MOVL	G^SCH$GL_CURPCB, R2	;Get pointer to our PCB.
	MOVL	UAF$L_UIC(R6),  -	;Move new UIC into
		PCB$L_UIC(R2)		;Process Control Block.
h
	CVTBW	UAF$T_DEFDEV(R6), -	;Complete descriptor for
0		NEW_DEVICE		;new SYS$DISK device.
	$CRELOG_S LOGNAM=SYS$DISK_NAME, - ;Use SYS$CRELOG service to
		EQLNAM=NEW_DEVICE, -	;change SYS$DISK name.
\		TBLFLG=#LOG$C_PROCESS, -
		ACMODE=#PSL$C_EXEC
$					;Let $CRELOG return status be
					;return status of KERNAL
					;routine.
P
	RET				;That's all in KERNEL mode.

|
GENERAL_ACTION:
D
	CMPL	R0, #SS$_SUPERSEDE	;Expect an old name replaced
	BEQL	10$			;return status from $CRELOG.
p	BLBS	R0, 10$
	$EXIT_S	R0
8
10$:	CVTBW	UAF$T_DEFDIR(R6), -	;Complete descriptor for
 		NEW_DIRECTORY		;new default directory.
d	PUSHL	#0
	PUSHL	#0
,	PUSHAQ	NEW_DIRECTORY		;Use system routine to set
	CALLS	#3, G^SYS$SETDDIR	;new default directory.
	$EXIT_S	R0
X

 	.END	NEW_START
