Operating System - OpenVMS
Showing results for 
Search instead for 
Did you mean: 

marry ssh session to bg device / local address


marry ssh session to bg device / local address


We have a piece of software that uses an alias Ip Address and we remove the alias when we stop the software ( it does it automatically as part of the closing procedure ) as it is used as a floating IP address.

The problem is that we have found users stopping the process when connected through ssh sessions using the floating IP address. This causes their session to drop out before the software has finished closing down properly.

We have a way of checking fot telnet connections where we use the sho user command to get the host field for the TNA device, then check all of the local host ip addresses in the bg devices where the service is telnet and the remote host matches the TNA host address. If any of them are found to be using the alias IP then we will not let them stop the software.

I know that this does not match exactly to the device and that they could be using the proper ip address and just have another session open using the alias but it does protect us.

Is there a way to do a silimar or better way to do the same for ssh sessions ( I would prefer a way to do it in DCL but I have no issues having to do it in a language such as C )



Respected Contributor

Re: marry ssh session to bg device / local address

If you want the process to only stop itself, can you (when you create the process) set the NODELETE bit?  This should prevent anyone from stopping the process. 


Re: marry ssh session to bg device / local address

Anyone should be able to stop the process just not if they are connected in via the alias address

David R. Lennon
Valued Contributor

Re: marry ssh session to bg device / local address

$! SSHWHO.COM - Find out which users are on SSHterms.
$! and where they are.
$! Malcolm MacArthur, 21 March 2002
$! Modifications:
$!      11-AUG-2015 - Dave Lennon - expanded to show SSH tunnels as well, etc.
$ set noon
$! num_controllers == 0
$ num_sshterms == 0
$ delete = "delete"
$! step 1: find the sshw$te_nnnn terminal controller processes.
$! pipe show system | search sys$pipe "sshw$te_"/output=sys$scratch:sshw$te.tmp
$ show system/noheading/nocluster/process=tcpip$s*_bg*/output=sys$scratch:sshw$te.tmp
$! get the pids...
$ close/nolog output
$ open/write output sys$scratch:sshwusers.tmp
$ close/nolog infile
$ open/read infile sys$scratch:sshw$te.tmp
$ pid = ""
$ read/end_of_file=endfile infile rec
$ pid = f$element(0," ",rec)
$! find the terminals connected to this controller..
$ call list_terminals 'pid'
$ goto loop
$ close infile
$ delete/nolog/noconfirm sys$scratch:sshw$te.tmp;
$ close output
$ sort sys$scratch:sshwusers.tmp sys$scratch:sshwusers2.tmp
$ delete/nolog/noconfirm sys$scratch:sshwusers.tmp;
$ if pid .eqs. "" then goto over_list
$ write sys$output -
  "      OpenVMS SSH User Processes at ''f$time()'"
$ write sys$output -
  "    Total number of SSH users = ''num_sshterms'"
$ write sys$output f$fao("!/ !12AS !6AS !16AS !8AS !8AS", -
  "Username","Node","Process Name","  PID","Terminal")
$ type sys$scratch:sshwusers2.tmp
$ delete/nolog/noconfirm sys$scratch:sshwusers2.tmp;
$! delete/symbol/global num_controllers
$ delete/symbol/global num_sshterms
$ exit
$! p1 = pid of TCPIP$* process
$ delete = "delete"
$ have_fta_dev = "true"
$ close/nolog outfile
$ open/write outfile sys$scratch:runsda.tmp
$ write outfile "$ define/user/nolog sys$error nl:"
$ write outfile "$ define/user/nolog sys$output sys$scratch:sdachans.tmp"
$ write outfile "$ analyze/system"
$ write outfile "$ deck"
$ write outfile "show process/id=''p1'/channels"
$ write outfile "$ eod"
$ write outfile "$ exit"
$ close outfile
$ @sys$scratch:runsda.tmp
$ delete/nolog/noconfirm sys$scratch:runsda.tmp;
$! type/page=save sys$scratch:sdachans.tmp
$! find the bgnn: device...
$ search/key=(pos:41,siz:2)/output=sys$scratch:bgchan.tmp sys$scratch:sdachans.tmp -
$ if $status .nes. "%X00000001" then goto nomoreterms
$! then the ftann: devices...
$ search/key=(pos:41,siz:2)/output=sys$scratch:ftachans.tmp sys$scratch:sdachans.tmp -
$ if $status .eqs. "%X08D78053"
$ then
$       have_fta_dev = "false"
$       search/output=sys$scratch:sshlog.tmp sys$scratch:sdachans.tmp -
$       close/nolog infile3
$       open/read infile3 sys$scratch:sshlog.tmp
$       read infile3 rec3
$       close infile3
$       log_file_name = f$edit(f$extract(40,999,rec3),"trim,compress") ! log file name
$       delete/nolog/noconfirm sys$scratch:sshlog.tmp;
$       search/output=sys$scratch:sshlog1.tmp 'log_file_name' -
        "NOTICE: User","coming from","authenticated."/match=and/nohighlight/exact/nowarnings
$       if $status .eqs. "%X08D78053"
$       then
$               username = "<login>"
$       else
$               close/nolog infile4
$               open/read infile4 sys$scratch:sshlog1.tmp
$               read infile4 rec4
$               close infile4
$               username = f$edit(f$element(0,",",f$extract(f$locate(": User ",rec4)+7,999,rec4)),"upcase,trim")
$       endif
$       delete/nolog/noconfirm sys$scratch:sshlog1.tmp;
$ endif
$ delete/nolog/noconfirm sys$scratch:sdachans.tmp;
$! open the file with the bgnn: device in it...
$ close/nolog infile2
$ open/read infile2 sys$scratch:bgchan.tmp
$ read infile2 rec
$ close infile2
$ bgdev = f$edit(f$extract(40,999,rec),"trim,compress") ! first BG device listed
$ delete/nolog/noconfirm sys$scratch:bgchan.tmp;
$! define/user sys$output nla0:
$! show display/symbol 'bgdev
$ accpornam = " "
$! accpornam = sshw$display_transport+"/"+sshw$display_node+":"+ -
$!              sshw$display_server+"."+sshw$display_screen
$! write out a record for the sshterm controller...
$! $ username = f$getjpi(p1,"username")
$! $ node = f$getjpi(p1,"nodename")
$! $ prcnam = f$getjpi(p1,"prcnam")
$! $ if f$length(accpornam) .le. 8 then -
$!    write output f$fao(" !12AS !6AS !16AS !8AS !8AS (!AS)", -
$!        username, node, prcnam, p1, bgdev, accpornam+ " [controller]")
$! $ if f$length(accpornam) .gt. 8 then -
$!    write output f$fao(" !12AS !6AS !16AS !8AS !8AS!/!#* (!AS)", -
$!        username, node, prcnam, p1, bgdev, -
$!        65-f$length(accpornam),accpornam+" [controller]")
$! $ num_controllers == num_controllers+1
$ define/user/nolog sys$output sys$scratch:bgdev.tmp
$ tcpip show device_socket 'bgdev'
$ close/nolog infile2
$ open/read infile2 sys$scratch:bgdev.tmp
$ read infile2 rec
$ read infile2 rec
$ src_ip = f$element(5," ",f$edit(rec,"trim,compress"))
$ close infile2
$ delete/nolog/noconfirm sys$scratch:bgdev.tmp;
$ accpornam = "SSH Host: ''src_ip'"
$ if .not. have_fta_dev
$ then
$       node = f$getsyi("nodename")
$       bgdev = f$edit(bgdev,"lowercase") - ":"
$       prcnam = "<Tunnel ''bgdev'>"
$       ownpid = pid
$       ftadev = "<None>"
$       goto over_fta
$ endif
$! well, wasn't that easy! ;-) now, get the user names for the terminal(s)...
$ close/nolog infile2
$ open/read infile2 sys$scratch:ftachans.tmp
$ read/end_of_file=nomoreterms infile2 rec
$ ftadev = f$edit(f$extract(40,999,rec),"trim,compress")
$ ownpid = f$getdvi(ftadev,"pid")
$ if ownpid .eqs. "00000000" ! no process...
$ then
$   username="<no process>"
$   node = f$getdvi(ftadev,"host_name")
$   prcnam = ""
$ else
$   username = f$getjpi(ownpid,"username")
$   node = f$getjpi(ownpid,"nodename")
$   prcnam = f$getjpi(ownpid,"prcnam")
$!   imagname = f$getjpi(ownpid,"imagname")
$!   image = f$parse(imagname,,,"name")
$!   if imagname .eqs. "LOGINOUT" then username = "<login>"
$ endif
$ if f$length(accpornam) .le. 21 then -
   write output f$fao(" !12AS !6AS !16AS !8AS !8AS (!AS)", -
       username, node, prcnam, ownpid, ftadev, accpornam)
$ if f$length(accpornam) .gt. 21 then -
   write output f$fao(" !12AS !6AS !16AS !8AS !8AS!/!#* (!AS)", -
       username, node, prcnam, ownpid, ftadev, -
$ num_sshterms == num_sshterms+1
$ if .not. have_fta_dev then goto end_the_sub
$ goto ftaloop
$ close infile2
$ delete/nolog/noconfirm sys$scratch:ftachans.tmp;



 I must admit my head hurt a bit trying to figure out what you are saying and wanting. Perhaps in the future if you provide example code of what works today and how you want to do the same thing in a different situation, that might help. Also stating exactly what your environment is, in particular which tcpip package you are running, would be good.

While I do not have DCL that does exactly what you want, please see the attached DCL command procedure that does the equivalent of a SHOW USERS/FULL on SSH terminals to display the ACCPORNAM (source ip). I bet it could be adapted or give you an idea on how to do what you are trying to accomplish. It is written for HP TCP/IP Services for OpenVMS (ucx),




Re: marry ssh session to bg device / local address

Thanks for that script Dave, I will be having a good look at it soon.

The reason why I did not specify the environment is that I want to use it across a set of environments ( Alpha & Itaniums ) with various versions of the tcpip / ucx  ( DEC / Compaq / HP / VSI ) or at least the ones that have ssh available.

I will explain what is going in a clearer way for you.

We have a process called wcsman and it is used to stop a whole set of processes in a clean way and perform some final post close clean up. 

The very last set of steps it has are to remove the alias, updates the logs with the final close time, update a special file to say that it was a clean close and what the next action should be and print to sys$output if there has been any issues during the process.

If the process is run by a user connecting in using the alias adress with telnet or ssh then as soon as the alias is removed then their session is killed and the process never finishes and this then causes issues when we come to start it up again.

All I want is a script that does a check and if you are connected in using the alias address then it says that you can't run this process.