SETUSER.BCK6 SETUSER.BCKNBACK *.* CMKRNL::[ANONYMOUS.SAVE_SETS]SETUSER.BCK/NOCRC/GROUP:0/BLOCK=8192/SAV AWPSYS d@lV5.1 _VAXB::  V5.0 )*[DCOLIB.MGR_UTILS.SETUSER]AAAREADME.TXT;3+,./ 4T<- 0123KPWO56@X@l7 AY@l89G HJ F SETUSER a Ultilty to a priviliged user to become another user.O*******************************************************************************@ NOTE: READ warning in SETUSER.MAR before using this softwareO*******************************************************************************0 Author: Andrew W. PotterA Rochester Institute of Technology7 One Lomb Memorial Drive9 Rochester, New York 14632 DESCRIPTION:I This program allows a privileged user (CMKRNL, PSWAPM, privs plusF read access to sysuaf) to change his username. It also changesH the users Account name, UIC, Process name, and Default Directory& to that of the specified user.C It now changes the group logical name table and changes the. owner of the JOB table. (14-Oct-1986).) NOTE: READ WARNING in SETUSER.MAR!!!!!!!E It is now written entirely in MACRO, and kernel mode stuff is+ all done in one call. (12-JUL-1988)? Modified to run under VMS V5.0, 5.0-1, 5.0-2, 5.1, 5.1-1 only!2 It should run under 5.2 *IF* DEC does not change " [SYS$LDR]LOGICAL_NAMES.EXE 2 AAAREADME.TXT This file.C BUILD_SETUSER.COM Build SETUSER from scratch.C MAKEFILE.MAK Makefile for use with MAKE.= MESSAGES.MSG Error message source.= MESSAGES.OBJ Error message object.@ OPRMSG.MAR Operator message source.@ OPRMSG.OBJ Operator message object.9 SETUSER.EXE Executable image.R SET_LOGICAL.MAR Module that defines the logicals (source).R SET_LOGICAL.OBJ Module that defines the logicals (object).S SET_PRCNAM.MAR Module that sets the process name (source).S SET_PRCNAM.OBJ Module that sets the process name (object).T SET_USER.MAR Module that contains the main code (source).T SET_USER.OBJ Module that contains the main code (object). INSTALLATION:2 1) Build SETUSER. Using BUILD_SETUSER.COM3 2) Place SETUSER in some utility directory.2 SETUSER is invoked as a foreign command7 $ SETUSER == "$DISK:[DIRECTORY]SETUSER" To use SETUSER: $ SETUSER username EX: $ SETUSER system Username: SYSTEM* Directory: SYS$SYSROOT:[SYSMGR] UIC: [1,4] PID: 0000002D Account: SYSTEM" The user is now SYSTEM.-*[DCOLIB.MGR_UTILS.SETUSER]BUILD_SETUSER.COM;2+,* ./ 4V- 0123KPWO56qA7 t*189f1G HJ$$! Creating SETUSER$$!$ write sys$output " "$ write sys$output -F "Have you read and understood the Warning found in SETUSER.MAR?" $ write sys$output " "<$ inquire foo "Answer NO now if you are in over your head!" $ if foo.eqs."" THEN FOO = "NO"'$ if .not.foo then write sys$Output " "E$ if .not.foo then write sys$Output "Thats probably the smart choice"6$ if .not.foo then write sys$Output "Have a nice day "$ if .not.foo then exit$$$ write sys$output " "$ write sys$output " "3$ write sys$output "ASSEMBLING AND LINKING SETUSER"$!"$ if "''p1'".nes."" then goto link9$ macro/nodebug set_user, set_logical, set_prcnam, oprmsg$ message messages$link:V$ link/exe=setuser/nodebug/notrace set_user, set_logical, set_prcnam, oprmsg, messages(*[DCOLIB.MGR_UTILS.SETUSER]MAKEFILE.MAK;1+,3./ 4P- 0123KPWO5 6g]76*189f1G HJP#*******************************************************************************P#* Makefile for SETUSER *P#* *P#* Created: 12-JUL-1988 *P#*******************************************************************************MAR_QUAL = /nodebug)LINK_QUAL = /exe\=setuser/nodebug/notraceMODULES = set_user \ set_logical \ set_prcnam \ oprmsg)setuser.exe : $(MODULES).obj messages.obj. link $(LINK_QUAL) $(MODULES), messages$(MODULES).obj : $*.marmessages.obj : messages.msg(*[DCOLIB.MGR_UTILS.SETUSER]MESSAGES.MSG;2+, ./ 4G- 0123KPWO56 7୮*189f1G HJ .title SETUSER messages.facility SETUSER,1.severity ERROR,ERROPENUAF /fao=0,ERRCLOSUAF /fao=08ERRSEARCH /fao=1@GETJPIERR /fao=0.severity WARNINGGCRELNMFAIL /fao=2.end#*[DCOLIB.MGR_UTILS.SETUSER]OLD.DIR;1+,* ./ 4- 0123 KPWO56f A7`2͢*189@ ojG HJIp  SETUSER.BCK!  &[DCOLIB.MGR_UTILS.SETUSER]OPRMSG.MAR;1X6&*[DCOLIB.MGR_UTILS.SETUSER]OPRMSG.MAR;1+,! ./ 4Xl- 0123KPWO5 6 \7*189f1G HJ* .title /Operator Message/; $opcdef $opcmsg;3 .psect opr_data, noexe, pic, noshr;Topmsg: .byte OPC$_RQ_RQST ; We want to request to the operatorQ .byte OPC$M_NM_CENTRL ; Send it to the central operatorA .word 0 ; Just null spaceA .long 0 ; Just null spaceQtext: .blkb 80 ; Place to put the message stringPOPMSGLEN = . - opmsg ; Length of the operator message;Xmsgdsc: .long OPMSGLEN ; Length of string to pass to sys$sndoprE .long opmsg ; Where the string is;;;P;*******************************************************************************P;* Oprmsg *P;* This procedure takes a string of up to 72 characters and sends it to *P;* the operators console. *P;*******************************************************************************;6 .psect opr_code, exe, pic, shr, nowrt;$ .entry oprmsg, ^m<>;E movl 4(ap), r0 ; Save string to send;N movc5 (r0), @4(r0), #32, #80, text ; Move the user string in> $sndopr_s msgdsc ; Send request;? ret ; End of oprmsg; .end'*[DCOLIB.MGR_UTILS.SETUSER]SETUSER.CLD;1+,./ 47p- 0123KPWO56 R7U*189f1G HJdefine verb setuser image mer$exe:setuser7 parameter p1, label=USERNAME, prompt="Username"+*[DCOLIB.MGR_UTILS.SETUSER]SET_LOGICAL.MAR;2+,. / 4Q - 0123KPWO 56_7 +*189f1G HJ# .title SET_LOGICAL .ident /01.2/P;*******************************************************************************P;* Set_logical *P;* This routine is intended to set all the necessary logical names for *P;* correct user context switch. *P;*******************************************************************************;. .library /SYS$LIBRARY:LIB.MLB/; $psldef $lnmdef;8 .psect lnm_data, noexe, pic, noshr, wrt;+$; Data for logical name redefinition;-/proc_direc: .ascid /LNM$PROCESS_DIRECTORY/#group_log: .ascid /LNM$GROUP/!job_table: .ascid /LNM$JOB/+proc_table: .ascid /LNM$PROCESS_TABLE/"sys_disk: .ascid /SYS$DISK/%sys_scratch: .ascid /SYS$SCRATCH/#sys_login: .ascid /SYS$LOGIN/*sys_login_dev: .ascid /SYS$LOGIN_DEVICE/$krnl_mode: .byte PSL$C_KERNEL krnl_mode_str: .ascid /KERNEL/"exec_mode: .byte PSL$C_EXEC#exec_mode_str: .ascid /EXECUTIVE/#supr_mode: .byte PSL$C_SUPER$supr_mode_str: .ascid /SUPERVISOR/"user_mode: .byte PSL$C_USERuser_mode_str: .ascid /USER/ lnm_item:lnm_buf_len: .word 16# .word LNM$_STRING$lnm_buf_adr: .address group_table" .address retlengthB .long 0 ; End of item list(lnm_ctrl_str: .ascid /LNM$GROUP_!6OL/grp_tab_des: .long 16$ .address group_tablegroup_table: .byte 32[16]Eretlength: .long 0 ; Dummy return length;;;6 .psect lnm_code, exe, pic, shr, nowrt;5 .entry set_logical, ^m;H movl 4(ap), r11 ; Save the device stringP movl 8(ap), r10 ; Save the default directory str@ movl 12(ap), r9 ; Save the group; pushl r9# pushab grp_tab_des# pushab lnm_buf_len$ pushab lnm_ctrl_strM calls #4, g^sys$fao ; Format the group table name; $crelnm_s -. tabnam = proc_direc, -- lognam = group_log, -- acmode = krnl_mode, -N itmlst = lnm_item ; Redefine group table in KRNL blbs r0, 10$; pushl r0% pushal krnl_mode_str! pushal group_log pushl #2+ pushl #SETUSER_CRELNMFAIL( calls #5, g^lib$signal;N10$: movw (r10), lnm_buf_len ; Move home dir into item listN movl 4(r10), lnm_buf_adr ; - for the following logicals $crelnm_s -- tabnam = job_table, -- lognam = sys_login, -- acmode = exec_mode, -J itmlst = lnm_item ; Define SYS$LOGIN in EXEC blbs r0, 20$; pushl r0% pushal exec_mode_str! pushal sys_login pushl #2+ pushl #SETUSER_CRELNMFAIL( calls #5, g^lib$signal;20$: $crelnm_s -- tabnam = job_table, -/ lognam = sys_scratch, -- acmode = exec_mode, -L itmlst = lnm_item ; Define SYS$SCRATCH in EXEC blbs r0, 30$; pushl r0% pushal exec_mode_str# pushal sys_scratch pushl #2+ pushl #SETUSER_CRELNMFAIL( calls #5, g^lib$signal;P30$: movw (r11), lnm_buf_len ; Move hom  SETUSER.BCK +[DCOLIB.MGR_UTILS.SETUSER]SET_LOGICAL.MAR;2Q H< e device into itm_listN movl 4(r11), lnm_buf_adr ; - for the following logicals $crelnm_s -- tabnam = job_table, -1 lognam = sys_login_dev, -- acmode = exec_mode, -Q itmlst = lnm_item ; Define SYS$LOGIN_DEVICE in EXEC blbs r0, 40$; pushl r0% pushal exec_mode_str% pushal sys_login_dev pushl #2+ pushl #SETUSER_CRELNMFAIL( calls #5, g^lib$signal;40$: $crelnm_s -. tabnam = proc_table, -, lognam = sys_disk, -- acmode = exec_mode, -I itmlst = lnm_item ; Define SYS$DISK in EXEC blbs r0, 50$; pushl r0% pushal exec_mode_str pushal sys_disk pushl #2+ pushl #SETUSER_CRELNMFAIL( calls #5, g^lib$signal;50$: $crelnm_s -. tabnam = proc_table, -, lognam = sys_disk, -- acmode = supr_mode, -J itmlst = lnm_item ; Define SYS$DISK in SUPER blbs r0, 60$; pushl r0% pushal supr_mode_str pushal sys_disk pushl #2+ pushl #SETUSER_CRELNMFAIL( calls #5, g^lib$signal;K60$: movl #1, r0 ; We completed successfully ret; .end**[DCOLIB.MGR_UTILS.SETUSER]SET_PRCNAM.MAR;1+,./ 4P- 0123KPWO5 6?KE \7 7D*189f1G HJ " .title SET_PRCNAM .ident /01.2/P;*******************************************************************************P;* Set_prcnam *P;* This routine is intended to set the current process's name to the *P;* given string. If it fails, it attempts to add a ":n", where "n" is a *P;* number from 0-99 inclusive. *P;*******************************************************************************;3 .psect prc_data, noexe, pic, noshr;Oprc_ctrl_str: .ascid /!AS:!UB/ ; Control string to set prcnameprocess_name: .long 15M .address prc_str ; New process name descriptorprc_str: .byte 32[15];;;6 .psect prc_code, exe, pic, shr, nowrt;0 .entry set_prcnam, ^m;N movl 4(ap), r10 ; Save the username descriptorL pushl r10 ; Try to set process name toD calls #1, g^sys$setprn ; - the new username% blbc r0, try_again;B ret ; Leave, we set it;Btry_again: clrl r11 ; Init our counterOloop: movl #15, process_name ; Make sure we only have 15 ch.; pushl r11 pushl r10$ pushal process_name$ pushal process_name$ pushal prc_ctrl_strM calls #5, g^sys$fao ; Format username with number;$ pushal process_nameI calls #1, g^sys$setprn ; Try to set process name! blbs r0, leave;D aobleq #99, r11, loop ; Try only 100 times;Pleave: ret ; Leave whether or not it worked; .end(*[DCOLIB.MGR_UTILS.SETUSER]SET_USER.MAR;9+,* .-/ 4l-+2- 0123KPWO,56 *A7[*189f1G HJ ;=; Please note. This code has been converted from VMS V4 and:; will run on VMS Version 5.0, 5.0-1, 5.0-2 and 5.1.;B; * WARNING * WARNING * WARNING * WARNING * * WARNING * WARNING *;;;L; This routine uses the executive routine LMM$SEARCHLOG. Under VMS V5J; LMN$SEARCHLOG is not a global routine. In order to continue usingG; this routine, we had to resort a major kluge. DEC did make theH; routine LMN$SEARCH_ONE globally vectorized. We find the addressE; of LMN$SEARCH_ONE in the vector table and subtract the lengthC; of LNM$SEARCHLOG from it (LNM$SEARCHLOG is positioned rightC; in front of LNM$SEARCH_ONE in the image LOGICAL_NAMES.EXE).@; this calculation gives us the address of LNM$SEARCH_LOG.;?; WARNING. If DEC does ANYTHING to change the length of F; LNM$SEARCHLOG or relocates it relative to LNM$SEARCH_ONE, ThisJ; program will BREAK. Although a Kernal mode handler is establishedH; to attempt to prevent a crash, you can't guarentee anything whenB; you blindly hop into system space in Kernal mode at IPL 2.;=; SO: WARNING! Before attempting to run this code onJ; any version of VMS other than the ones I have listed above, VERIFYL; with SDA that the start of LNM$SEARCHLOG occurs exactly 93 Hex bytes@; in front of LNM$SEARCH_LOG. Having the MicroFiche helps.;:; You could also check by checking to see if DEC relinked A; SYS$LOADABLE_IMAGES:LOGICAL_NAMES.EXE with ANALYZE/IMAGE.;H; Why all this trouble just to change the ownership of the JOB table??;F; We feel that a Change USERNAME program is not complete withoutI; being able to change the ownership of the JOB logical name table.C; This version uses LNM$SEARCH_LOG to find the address of the9; JOB logical name table to facilitate this change.;C; By changing the ownership of the table, you can then remove>; privileges (except for TMPMBX) and spawn giving a good>; approximation of of non-privileged context for testing=; questionable software. If you don't change ownership@; of the JOB table, then SPAWN will be unable to place itsD; logical name for the DCL context mailbox into the JOB table.;;; ; .title SET_USER .ident /01.2/;5 .library /SYS$LIBRARY:LIB.MLB/E .link "SYS$SYSTEM:SYS.STB"/SELECTIVE_SEARCH;;  SETUSER.BCK*  ([DCOLIB.MGR_UTILS.SETUSER]SET_USER.MAR;9l-7O $pcbdef ; Process Control Block offsetsO $jibdef ; Job Information Block offsetsN $phddef ; Process Header Block offsetsJ $lnmstrdef ; Logical name definitionsJ $orbdef ; Object rights block defsC $lnmdef ; Logical name defsD $ipldef ; Processor IPL defs> $psldef ; PSL bit defsL $uafdef ; User Auth Database offsets;;;3 .psect rms_data, noexe, pic, noshr;+4; Data used in retrieving SYSUAF records through RMS;-#infab: $fab fac = get -( fnm = -1 dnm = -/ shr = ;%inrab: $rab fab = infab -( kbf = usekey+8 -! krf = 0 -" ksz = 12 -# rac = key -# rop = nlk -& ubf = inbuff -" usz = 2048;&usekey: .ascid / /inpline: .word 0$usrprmt: .ascid /Username: /;dir_descr: .long 32 .address defdirdefdir: .byte 32[32];dev_descr: .long 16 .address defdevdefdev: .byte 32[16];def_descr: .long 48 .address def_bufdef_buf: .byte 32[48];;;3 .psect fao_data, noexe, pic, noshr;+A; Data used in formating messages to screen and operators console;-lterm_ctrl_str: .ascid "!/Username: !AS!/Directory: !AS!/UIC: !%U!/PID: !XL!/Account: !AS!/"term_message: .long 256! .address term_msgterm_msg: .byte 32[256]term_fao_arg: .long 8& .address term_ctrl_str% .address term_message% .address term_message# .address user_descr" .address def_descrterm_uic: .long 0term_pid: .long 0# .address acct_descr;Noper_ctrl_str: .ascid /SETUSER: User !AS, (PID: !XL) became !AS, (UIC: !%U)/oper_message: .long 80! .address oper_msgoper_msg: .byte 32[80]oper_fao_arg: .long 7& .address oper_ctrl_str% .address oper_message% .address oper_message' .address old_user_descroper_pid: .long 0# .address user_descroper_uic: .long 0;;;3 .psect jpi_data, noexe, pic, noshr;+ ; Data returned from SYS$GETJPIW;-?uic: .long 0 ; Process's UICHgroup: .long 0 ; Process's group numberImember: .long 0 ; Process's member numberEpid: .long 0 ; Process's ID number;acct_descr: .long 8 .address accountHaccount: .blkb 8 ; Descriptor for account;old_user_descr: .long 12& .address old_user_nameMold_user_name: .blkb 12 ; Descriptor for old username;user_descr: .long 12! .address usernameIusername: .blkb 12 ; Descriptor for username;term_descr: .long 7! .address terminalIterminal: .blkb 7 ; Descriptor for terminal;Kretlength: .long 0 ; Dummy return length place;Iold_username: .word 12 ; Length for the usernameF .word JPI$_USERNAME ; We want the usernameK .address old_user_name ; Where to put the usernameJ .address old_user_descr ; How long our username is;G .long 0 ; End of single request;Ljpi_item: .word 4 ; Length for the processs IDH .word JPI$_PID ; We want the process IDO .address pid ; Where to store the process IDE .address retlength ; Dummy return length;L .word 4 ; Length for the process UICK .word JPI$_UIC ; We want the process's UICH .address uic ; Where to store the UICE .address retlength ; Dummy return length;I .word 12 ; Length for the usernameF .word JPI$_USERNAME ; We want the usernameK .address username ; Where to put the usernameJ .address user_descr ; How long our username is;H .word 8 ; Length for the accountE .word JPI$_ACCOUNT ; We want the accountJ .address account ; Where to put the accountE .address retlength ; Dummy return length;N .word 7 ; Length want for the terminalQ .word JPI$_TERMINAL ; Get the terminal of the processK .address terminal ; Where to put the terminalE .address term_descr ; Dummy return length;N .word 4 ; Length for the member numberI .word JPI$_MEM ; We want a member numberP .address member ; Where to put the member numberE .address retlength ; Dummy return length;M .word 4 ; Length for the group numberL .word JPI$_GRP ; We want a the group numberO .address group ; Where to put the group numberE .address retlength ; Dummy return length;A .long 0 ; End of JPI list;;;4 .psect krnl_data, noexe, pic, noshr;+; Data used in kernel mode;-lock_dat_beg: .long 0lock_dat_end: .long 0lock_code_beg: .long 0lock_code_end: .long 0;new_uic: .long 0inbuff: .blkb 2048;!table: .ascid /LNM$JOB/#lognam: .ascid /SYS$LOGIN/mutex_flag: .long 0;Oend_dat: ; End of data used in KRNL mode;;;7 .psect user_code, exe, pic, shr, nowrt;+; Main program entry point;-& .entry set_user, ^m<>; $getjpiw_s -F itmlst = old_username ; Get the old username; blbs r0, 10$; pushl r0 pushl #0* pushl #SETUSER_GETJPIERR& calls #3, g^lib$stop;10$: pushaw inpline pushal usrprmt pushal usekey> calls #3, g^lib$get_foreign ; Get username blbs r0, 20$;? ret ; Exit  SETUSER.BCK*  ([DCOLIB.MGR_UTILS.SETUSER]SET_USER.MAR;9l-< on error;20$: pushal usekey pushal usekey pushal usekeyK calls #3, g^str$trim ; Trim the username read in;K tstw usekey ; Test if anything is there bneq open_uaf;E movl #1, r0 ; Leave with no error ret;=open_uaf: $open fab = infab ; Open SYSUAF' blbs r0, connect_uaf; pushl r0 pushl #0+ pushl #SETUSER_ERROPENUAF& calls #3, g^lib$stop;Hconnect_uaf: $connect rab = inrab ; Establish a connection# blbs r0, get_rec; pushl r0 pushl #0+ pushl #SETUSER_ERROPENUAF& calls #3, g^lib$stop;Aget_rec: $get rab = inrab ; Read UAF record% cmpl r0, #RMS$_RNF" beql error_stop;( cmpl r0, #RMS$_NORMAL$ beql close_sysuaf;error_stop: pushl r0 pushal usekey pushl #1* pushl #SETUSER_ERRSEARCHJ calls #4, g^lib$stop ; Signal and stop on error;;close_sysuaf: $close fab = infab ; Close UAF' blbs r0, begin_locks; pushl r0 pushl #0+ pushl #SETUSER_ERRCLOSUAF& calls #3, g^lib$stop;+; lock code and data into working set;2begin_locks: moval lock_dat_beg, lock_dat_beg- moval end_dat, lock_dat_end $lckpag_s -, inadr = lock_dat_beg blbs r0, 20$;@ ret ; Leave on error;.20$: moval kerstuf, lock_code_beg0 moval kerstuf_e, lock_code_end $lckpag_s -- inadr = lock_code_beg blbs r0, 30$;@ ret ; Leave on error;<; Pick up address of just read UAF record (now locked);-30$: movl inrab + rab$l_rbf, r7) movl uaf$l_uic(r7), r8# movl r8, new_uic;; go kernel mode;F $cmkrnl_s change_user ; Make us the new user blbs r0, 40$; ret;G40$: $cmkrnl_s change_logs ; Change logical tables blbs r0, 50$;@ ret ; Leave on error;; Allow paging again;50$: $ulkpag_s -J inadr = lock_dat_beg ; Don't care if these fail $ulkpag_s -- inadr = lock_code_beg;, movzbl uaf$t_defdev(r7), r6L movc3 r6, 1+uaf$t_defdev(r7), defdev ; Move to descriptor% movl r6, dev_descr;, movzbl uaf$t_defdir(r7), r8L movc3 r8, 1+uaf$t_defdir(r7), defdir ; Move to descriptor% movl r8, dir_descr;+ movc3 r6, defdev, def_bufH movc3 r8, defdir, (r3) ; Concat into one string) addl3 r6, r8, def_descr;M $getjpiw_s - ; Get all of our process info; itmlst = jpi_item ; - we need; blbs r0, 10$; pushl r0 pushl #0* pushl #SETUSER_GETJPIERR& calls #3, g^lib$stop;10$: pushl group! pushal def_descr! pushal dev_descrI calls #3, set_logical ; Set the proper logicals;" pushal user_descr" pushal user_descr" pushal user_descrN calls #3, g^str$trim ; Trim current username string;& pushal old_user_descr& pushal old_user_descr& pushal old_user_descrN calls #3, g^str$trim ; Trim the old username string;F pushal user_descr ; Set the process name& calls #1, set_prcnam; clrq -(sp)! pushal def_descrK calls #3, g^sys$setddir ; Set the default directory;% movl uic, oper_uic% movl pid, oper_pidP callg oper_fao_arg, g^sys$fao ; Format a message for operators;$ pushal oper_messageB calls #1, oprmsg ; Send the message;% movl pid, term_pid% movl uic, term_uicS callg term_fao_arg, g^sys$fao ; Format a message for the terminal;$ pushal term_messageP calls #1, g^lib$put_output ; Send a message to the terminal;' movl #SS$_NORMAL, r0 ret;;;: .psect kernel_code exe, pic, noshr, nowrt;Hkerstuf: .entry change_user, ^m;+G; Set our IPL to SYNCH so that we can access the system wide databases.;- LOCK SCHEDG movl ctl$gl_pcb, r11 ; get PCB addr into r11< movl r8, pcb$l_uic(r11) ; R8 has UICI movl pcb$l_jib(r11), r10 ; pick up addr of the JIB;2; Move username and account into JIB and CTL;D movc3 #12, uaf$t_username(r7), jib$t_username(r10)? movc3 #12, uaf$t_username(r7), ctl$t_usernameA movc3 #8, uaf$t_account(r7), jib$t_account(r10)< movc3 #8, uaf$t_account(r7), ctl$t_account; UNLOCK SCHED movl #1, r0 retr; ;m;SH .entry change_logs, ^m;*M movab handler, (fp) ; Establish condition handler ;+P; Set our IPL to AST delivery level so that there are no interruptions while theN; translation of the logical name is being carried out. Then lock the logicalN; name mutex for reading, and then search for the specified logical name. TheP; internal routine from LNMSUB in the VMS source, LNM$SEARCHLOG, finds a logicalJ; name and returns the address of the table it is under. We then move theJ; arguments into the appropriate registers for LNM$SEARCHLOG, and make the>; call. When we are done, we lower our IPL back down to zero.;-Q setipl s^#ipl$_astdel, - ; Lower IPL to AST delivery levele, environ=uniprocessorI jsb g^lnm$lockr ; Lock tables for readingg; P movb #1, mutex_flag ;*Note elevated IPL & mutex heldM movq lognam, r0 ; Get logical name descriptor K movq table, r2 ; Get table name descriptoreL bicl #^xffff0000, r0 ; Clear the upper bits of R08 bicl #^xffff0000, r2 ; and R2O movl #3, r5 ; Set R5 to it's required value ;+E; Call to LNM$SEARCHLOG expects the following registers to be set up: ; *; R0 - length   SETUSER.BCK*  ([DCOLIB.MGR_UTILS.SETUSER]SET_USER.MAR;9R;2l-r$of logical name string+; R1 - Address of logical name stringj(; R2 - Length of table name string); R3 - Address of table name stringR,; R5 - Search access mode in low byte,$; caseless flag in bit 8,; high order word 0. ; Returns:;n2; R0 low bit clear indicates search failure.@; R0 - SS$_NOLOGNAM - No logical name match found.I; R1 - Address of logical name block on which search failedr;l-; R0 low bit set indictes success with:dF; R1 - Address of logical name block that contains match;u); All other registers are preservedw;-;+-; PLEASE TAKE HEED !!!!u;lI; WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNINGO;aG; KLUGE KLUGE KLUGE KLUGE KLUGE KLUGE KLUGE KLUGE KLUGE ;iI; WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ; J; The following three lines is a MAAAAAJOR kluge! In VMS V5 and access toI; system entry points were vectorized. Some routines were not consideredtM; necessary enough to be vectorized. So, we cannot JSB or CALL those routinesH; not vectoried. BUT, in order that we can call LNM$SEARCHLOG, which weJ; need in order to get the address of our job table, we have KLUGED around; this.s; I; Vectors for routines called by JSB are 8 bytes long and look like this: ; %; JMP L^FOO ; .BLKB 2 ; H; Now, in looking through VMS Microfiche, we noticed that LNM$SEARCH_ONEE; begins right after the end of LNM$SEARCHLOG. What we do is use the K; universal symbol LNM$SEARCH_ONE to get the address of the JMP instruction I; above. The JMP instruction is two bytes long so we add 2 to the symbolFI; LNM$SEARCH_ONE to get to the address JMP jumps to. That address is the H; actual virtual address of the routine LNM$SEARCH_ONE. Subtracting theL; length of LNM$SEARCHLOG from that address gets the start of LNM$SEARCHLOG.M; We found the length of LNM$SEARCHLOG by looking through the VMS Microfiche. ; ; ;-P movl g^LNM$SEARCH_ONE+2, r11 ; Address after jump instructionO subl2 #^X93, r11 ; Subtract length LNM$SEARCHLOG O; ************* ^^^ *************************************************l; ^^^:1; Check this value at EVERY release of VMSl; ;2N jsb (R11) ; KKKLUGE!! goto LNM$SEARCHLOGH movl r0, r10 ; Save the search statusI blbc r0, 20$ ; Branch if no name found;_M movl lnmb$l_table(r1), r1 ; Get address of table header,T movl lnmth$l_orb(r1), r1 ; Get address of object rights blockP movl r8, orb$l_owner(r1) ; Set the new owner of the table; O20$: jsb g^lnm$unlock ; Release lock on logical mutexs;rF setipl #0, - ; Drop our IPL to zero, environ=uniprocessorK clrl mutex_flag ; Clear the mutex-held flag I movl r10, r0 ; Move return status back ;  retd; ;+K; This is the condition handler in case anything happens during kernel mode ; execution.;-% .entry handler, ^m<>p;m> tstl mutex_flag ; Mutex held ?C beql 10$ ; Branch if nope... C jsb g^lnm$unlock ; Release our mutex F setipl #0 ; Drop our ipl to zero;G10$: $exit_s ; Cause process to exitc kerstuf_e:; .end set_userct jpi_data, noexe, pic, noshr;+ ; Data returned from SYS$GETJPIW;-?uic: .long 0 ; Process's UICHgroup: .long 0 ; Process's gr