[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference humane::scheduler

Title:SCHEDULER
Notice:Welcome to the Scheduler Conference on node HUMANEril
Moderator:RUMOR::FALEK
Created:Sat Mar 20 1993
Last Modified:Tue Jun 03 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:1240
Total number of notes:5017

1119.0. "Security and Audit" by ROM01::CALDONI () Fri Jun 14 1996 08:28

    A customer have some compliant about Scheduler Security.
    
    He have some jobs that run under privileged account; many operator has
    granted the execute id registered for these jobs so they can run the jobs.
    
    The customer would like to trace any run of these jobs under the
    Security Tools of OpenVMS to understand who runs what.
    
    I tried to set:
    
    $ SET AUDIT/AUDIT/ENABLE=LOGIN=DETACHED
    
    but this command inform about the creation of the process, but no info
    about who create it.
    
    Any hint ?
    
    Gaetano
    		
    P.S. The jobs are created as detach processes 
T.RTitleUserPersonal
Name
DateLines
1119.1there is an (unsupported) wayRUMOR::FALEKex-TU58 KingFri Jun 14 1996 14:5724
    As you noticed, the set audit command doesn't tell you who requested
    execution of Scheduler jobs.
    
    However, there is an unsupported utility for scheduler V2.x (shipped in
    the VMSINSTAL saveset as source code) that can capture this information.
    It listens to real time messages used by the scheduler system, and prints
    information about changes in job state and commands performed on jobs
    (requests to run, abort, hold, modify, etc. jobs but not information
    about which fields were modified). This utility is not part of the
    product and is NOT waranteed or supported by Digital.
    
    If you want to try this, extract files SCHED_LISTEN.BAS and MSG_AST.BAS.
    from the saveset. Instructions are in SCHED_LISTEN.BAS. You need a
    BASIC compiler to compile it, and you need to have file
    NSCHED$:NSCHED_SUBS.OLB (at product installation time, there is an
    option to save sapce by not getting that file).
    
    If you perfer, you can also copy these files or the pre-built executable,
    SCHED_LISTEN.EXE file from RUMOR::NSCHED$:
    
    You can run it on a terminal or you can redefine sys$output to capture
    the output in a file. The program requires SYSLCK privilege - either
    the account that runs it must have SYSLCK, or it must be installed with
    SYSLCK.
1119.2Can't get SUCCESS or FAILURE statusROM01::CALDONIMon Jul 29 1996 08:576
    I'm trying SCHED_LISTEN.BAS and it's quite fine. But SUCCESS or FAILURE
    messages are never trapped (in code mtype = 5 or mytpe = 6). I need to 
    know the end status of a runned job. Can you help me? Looks like a bug.
    
    Thanks,
    Gaetano
1119.3they don't send the info - but here's a work-aroundRUMOR::FALEKex-TU58 KingMon Jul 29 1996 14:50291
    It looks like the scheduler developers took out messages of MTYPE 5 and
    6 somewhere along the line because they could get along without them by
    getting the completion status directly from the scheduler database when
    the GUI gets a job completion message (or so I guess). Fortunately, we
    can do the same thing. I modified MSG_AST.BAS to call VSS$NUM_TO_NAME
    when a job completes. This returns the job completion status (as well
    as jobname, username, other things). The modified version will print
    the completion status for you. Note that you need scheduler read access
    to a job to see information about it.
    
    To try this out, extract the new MSG_AST.BAS below, or copy it from
    RUMOR::NSCHED$:MSG_AST.BAS. Then
    $ basic MSG_AST
    $ link sched_listen,msg_ast,nsched$:nsched_subs/lib,sys$library:vaxcrtl/lib
    
    ----------------------------------------------------------------------
	SUB MSG_AST ( long OUR_PARAM, R0, R1, PC, PSL)

	! Copyright 1989,1992 Digital Equipment Corporation
   	! DECscheduler V1.1A, T2.0
	! Modified 7-29-96 by Lou Falek to get exit status of completed
	!  jobs, since scheduler apparently no longer sends messages of
	!  MTYPE=5 or 6	

	! Blocking AST for SCHED_LISTEN program.
	! This program is UNSUPPORTED. 
	! It can be used to display in real time changes in the status of
	! DECscheduler jobs.

	! This blocking AST recieves VAXcluster broadcasts
	! which are sent whenever a Scheduler changes the state of a job.
	! It is triggered when the Scheduler calls TELL_GUIDO (in NSCHED_SUBS)
	! to send a message. TELL_GUIDO puts a message in the GUIDO_MSG
	! lock value block, then requests a lock on "GUIDO_SIGNAL" in EX-mode,
	! We never actually give up our lock on GUIDO_SIGNAL, rather, we
	! call $GETLKIW to get the info from the GUIDO_MSG lock value block. 

   	! Note that this AST only receives the LATEST message sent.
   	! If messages are sent more quickly then they are read, they are
   	! over-written (not queued).

	OPTION TYPE = EXPLICIT
	external long function sys$getlkiw,sys$enqw,lib$wait,lib$date_time,&
   		sys$exit,lib$getjpi
	external long constant msg_ast,ss$_valnotvalid

	declare long constant		&
	lck$m_system=X'00000010'L,	&
	lck$m_valblk=X'00000001'L,	&
	lck$m_convert=X'00000002'L,	&
	lck$k_nlmode=X'00000000'L,	&
	lck$k_crmode=X'00000001'L,	&
	lck$k_exmode=X'00000005'L,	&
	lck$m_nodlckwt=X'00000200'L

	declare word constant lki$_valblk=X'203'W,  ! to request value block &
			      lki$_locks=X'208'W    ! to request info on locks

	declare long cstatus,flags,number_of_locks,i
	declare string old,new, info_state,who,user

	! SCHED_LISTEN.BAS (which we're linked with) uses same lock$block map
	map (lock$block) word cond,word fill,long lock_id, string msg=16%, &
			long s_lblk(1%),string current_time=20%

	! description of lock status/value block fields for message lock
	map(mbuf) string ret_buffer=16%,long buff_len ! for returned info
	map(mbuf) long jobnum,string mtype=1%,string old_state=1%,&
   		new_state=1%,string fill$=3,string sender=6%
	map(mbuf) long jobnum,string mtype=1%,string operation=1%,&
   		long pid,string sender=6%
	map (mbuf) string signals_info=1024% ! info on all signal locks
	
	! description of lock info returned by $GETLKIW for signal lock(s)
	map(msignal) long s_lockid,long s_opid, long s_sid, &
		   byte s_reqmode, byte s_grmode, byte s_que, byte s_fill, &
		   long s_remid, long s_remsid
	map(msignal) string one_lock=24% ! buffer for info about one signal lock


	record item_list		! declare item_list structure
		word buffer_len		! for system services
		word item_code
		long buff_addr
		long ret_len_addr
		long end_list
	end record item_list
	declare item_list items			! fill in the item list
	
	DEF string long_to_hex(long inlong) 	! longword to HEX string
	! convert a longword to a hexadecimal string
   	external long function ots$cvt_l_tz
	declare string hex_string
	hex_string=space$(8%)
	cstatus=ots$cvt_l_tz(inlong,hex_string,8% by value,4% by value)
	long_to_hex=hex_string
	END DEF

	! Call SYS$GETLKIW to get the value block for the GUIDO_MSG lock
	! fill in item list for call to $GETLKIW
	items::item_code=lki$_valblk		! value block wanted
	items::buffer_len=16%			! our buffer length
	items::buff_addr=loc(ret_buffer)	! addr. of ret_buffer
	items::ret_len_addr=loc(buff_len)	! addr of length of retd. info
	items::end_list=0			! terminator

	cstatus=sys$getlkiw( ,! efn	    &
			lock_id,! lock-id addr  &
			items,	 ! item list	    &
			,,,)

	if cstatus<>1% then	! error	&
		print "MSG_AST: GETLKIW error : ";cstatus
		cstatus=sys$exit(cstatus by value) ! exit program
	end if

	! parse the value block
	! The format is  job_number (longword), mtype (byte) (changed in V1.1A)
	! data for state change msg (mtype="0") :
	! 	old_state (1 byte) new_state (1 byte) sender_node (6 bytes)
   	! data for create/modify msg (mtype="1") :
   	! 	operation (1 byte = "C" or "M"
   	!	PID that did it (long)
   	!	sender node (6 bytes)
   	! data for informational msg (mtype="2") : see code

	cstatus=lib$date_time(current_time)	! get current time
	


   	if mtype="5"  then ! local job success completion   &
		print current_time;" Job";jobnum; &
   		 "completed with SUCCESS status on ";trm$(sender)
   		goto re_set
   	else
   		if mtype="6"  then ! local job success completion   &
			print current_time;" Job";jobnum; &
   		 	"completed with FAILURE status on ";trm$(sender)
   			goto re_set
   		end if
   	end if

   	if mtype="0" then ! job state change &
		! make understandable strings out of 1 byte states
		select old_state
		case = "S"
			old="Scheduled"	
		case="J"
			old="Job Slot Wait"	
		case="R"
			old="Running"
		case="D"
			old="Job dependency wait"
		case="H"
			old="Holding"
   		case="Q"
   			old="Queued"
		case else
			old=old_state
		end select

		select new_state
		case = "S"
			new="Scheduled"	
		case="J"
			new="Job Slot Wait"
		case="R"
			new="Running"
		case="D"
			new="Job dependency wait"
		case="H"
			new="Holding"
   		case="Q"
   			new="Queued"
		case else
			new=new_state
		end select

		print current_time;" Job";jobnum;"changed from "; &
		    old;" to ";new;" on ";trm$(sender)

	        ! code added by LF 7-29-96 to get the completion status of jobs 
		external long function vss$num_to_name
		! gets job name, username, state, compl. status from job number
		declare string ret_name_and_username,job_status,ret_jobstate
		declare long ret_jobstat
		if old_state="R" and new_state<>"R" then &
		    ! a job completed, get and print completion status
       		    cstatus=vss$num_to_name(jobnum,"",ret_jobstat,&
		      ret_jobstate, ret_name_and_username)
		    if (cstatus <> 1) then &
                        print "  Couldn't read completion status for job ";jobnum; " ";cstatus
           	    else
                        job_status=long_to_hex(ret_jobstat) ! convert to hex string
	                 if (ret_jobstat and 1%)=1% then &
			    print "  Completion Status: Success (";job_status;")"
                         else
                            print "  Completion Status: Failure (";job_status;")"
                    
			 end if
		   end if
		end if
		goto re_set
   	end if
	! end of new code to show completion status

	if mtype="1"  then ! user-interface command &
		cstatus=lib$getjpi(X'202'L,pid,,,user,)! pid to user
   		who=" Username="+trm$(user)+", PID="+long_to_hex(pid)
		print current_time;" Job";jobnum;
   		select operation
   		case="M"
			print "Modified by";who
   		case="C"   			
   			print "Created by";who
   		case="D"		
   			print "Delete Requested by";who
   		case="A"
			print "Abort Requested by";who
   		case="H"
			print "Hold Requested by";who
   		case="U"
			print "Release Requested by";who
   		case="N"
			print "Run Requested by";who
   		case="R"
   			print "Deleted from job database by server"
   		case else
   			print "Operation = ";operation
   		end select 	
		goto re_set
	end if


   	if mtype="2" then ! informational msg from NSCHED &
   		info_state = old_state+new_state
   		select info_state
   		case = "XR"
			new="Exceeded maximum run-time"
		case = "XS"
			new="Exceeded maximum stall-time without starting"
		case else
			new="Unknown informational event"+" "+info_state
		end select
		print current_time;" Job";jobnum;new;" on ";trm$(sender)
   		goto re_set
   	end if

   re_set:	
	! loop until sender has $deq'd lock request
	! call $getlkiw until no more requestors are waiting

	! fill in item list code for call to $GETLKIW
	items::item_code=lki$_locks		! get info on all SIGNAL locks
	items::buffer_len=1024%			! up to 1024 bytes total
	items::buff_addr=loc(signals_info)	! addr. of ret_buffer
	get_info:
	cstatus=sys$getlkiw( ,! efn	    &
		s_lblk(1%),! lock-id of SIGNAL lock &
		items,	 ! item list	    &
			,,,)

	print "bad status from GETLKIW (signal) : ";cstatus if cstatus<>1%
	number_of_locks=(buff_len and 65535%)/24% ! save returned info

	for i=number_of_locks-1% to 0% step -1%
		! backwards because EX requested lock is usually last
		lset one_lock=seg$(signals_info,(i*24%)+1%,(i*24%)+24%)
		if (s_reqmode=lck$k_exmode) then ! talker's still queued &
			cstatus=lib$wait(0.1)	! wait 0.1 sec, save SCS
			goto get_info						
		end if
	next i

	! convert GUIDO_SIGNAL lock from CR to CR to reset blocking AST
	cstatus=sys$enqw	( ,		! efn		&
		lck$k_crmode by value,	! lkmode	&
		s_lblk() by ref,	! status_block	&
		lck$m_system or lck$m_nodlckwt or lck$m_convert by value, &
		"GUIDO_SIGNAL",		! resource name (ignored for converts) &
		,			! parent id	&
		,			! ast addr	&
		,			! ast parm	&
		MSG_AST by value,	! blocking ast	&
		,	)		! access mode,null
	if not cstatus and 1% then
		print "MSG_AST: SIGNAL lock CR-CR ERROR: ";cstatus;
		exit sub
	end if

	END SUB
1119.4Don't have nsched_subs libROM01::CALDONITue Jul 30 1996 07:475
    Thanks a lot, but for my own curiosity, why message types 5 and 6 do
    not show up?. Aren't thet written to the value block? Is it possible
    not to use the nsched_sub library?
    
    Tano 
1119.5they don't get sentRUMOR::FALEKex-TU58 KingTue Jul 30 1996 10:469
    They don't get sent by NSCHED. Apparently, it was decided that they
    were superfluous and so they were removed to reduce the number of
    messages that get sent. The GUI uses the VSS$NUM_TO_NAME method to get
    the status, like I added to the MSG_AST example. 
    
    The NSCHED_SUBS.OLB on RUMOR::NSCHED would probably be OK for you to
    use to link your code. Once its linked, you can delete NSCHED_SUBS.OLB.
    (NSCHED_SUBS is provided if you answer YES to the "Do you want the
    callable interface" question during product installation).