Article 3697 of vmsnet.sysmgt: In article <1996Apr9.085240.1753@hccompare.com>, kaplowro@hccompare.com wrote: >I don't mind having to hard-code a list of node names to update, and can't >think of a way to avoid this anyway. I don't want a file left anywhere with >the passwords in it, although I realize that I'll have to live with network >packets wizzing around with unencrypted passwords. I envision some command >file that prompts me for the old and new (twice of course) system passwords, >and then goes off and does its thing. Anyone got a handy tool to automate >this? Hi Bob. I use SYNCHRO. It copies a "temporary" file to the target node/user which does a SET PASSWORD, and then deletes it. To use it, $ @SYNCHRO [echo] If *any* argument is passed, it disables the SET TERM /NOECHO so you can see the passwords as you type them. Nothing like entering the password incorrectly _twice_, and having ALL of your user IDs messed up!! It's useful when _noone_ is around. Edit SYNCHRO.DAT with your node names and user names. Of course all of the user records must already have the same password. It's fast enough that if you feel paranoid, you can change all your IDs' passwords to something new in in just a minute or two. Simply extract SYNCHRO.COM. It may need some cleanup; don't know if my news program wrapped some lines or not. Then simply run it. When it's done, you'll have a SYNCHRO.LOG that looks like: Processing user SSMITH on node VAXA 5-APR-1996 09:48:23.81 Remote exec status = %SYSTEM-S-NORMAL, normal successful completion Processing user SYSTEM on node VAXA 5-APR-1996 09:48:39.15 Remote exec status = %SYSTEM-S-NORMAL, normal successful completion Processing user FIELD on node VAXA 5-APR-1996 09:48:53.32 Remote exec status = %SYSTEM-S-NORMAL, normal successful completion . . . o / o / o / o / --SYNCHRO.DAT----X---------------X---------------X---------------X---- o \ o \ o \ o \ ! Synchro accepts comment (!) lines and blank lines VAXA SSMITH VAXA SYSTEM VAXA FIELD VAXB SMITH VAXA SYSTEST VAXC SSMITH ! | | ! | +--- username on remote node ! +--- remote node (can also be local node of course) o / o / o / o / -SYNCHRO.COM-----X---------------X---------------X---------------X---- o \ o \ o \ o \ $ verify_context = 'f$verify(0+f$trnlnm("SYNCHRO$DEBUG"))' $ set noon $ $!---------------------------------------------------------------------------- ----------------------- $! SYNCHRO.COM $! $! Aug'92 -- Original version [N.Staes] $! - Synchronizes passwords on different systems $! - Procedure name may be changed (not necessarily SYNCHRO.COM) $! - System and user names must be present in a .DAT file with the same name $! as the procedure (Ex: JOB.COM & JOB.DAT) $! - This file contains NODENAMES and USERNAME pairs (EX: KETJE STAES) and may contain $! blank records, or comments (! symbol) $! - Does not require proxy accounts to be present $! - Duplicates itself prior to execution $! - Deletes itself after execution $! $! version 2.0 $! - Record termination status is .LOG file $! $! On the whishlist: $! - better error checking and handling, especially the remote part $! $!---------------------------------------------------------------------------- ------------------------ $!-- Dispatch according LOCAL or REMOTE function -- $ $ if f$trnlnm("SYS$NET") .nes. "" then goto Execute_function $ $!---------------------------------------------------------------------------- ------------------------ $! $! This part of the code executes on the LOCAL node (REQUESTOR) $! $ $!-- Load file specifications and symbols -- $ $ put := write sys$output $ log := write/err=log_err log_fil $ com_spec = f$environment("PROCEDURE") $ com_nam = f$parse(com_spec,,,"NAME") $ dat_spec = f$parse(".DAT;",com_spec) $ tmp_spec = f$parse(".TMP;",com_spec) $ log_spec = f$parse(".LOG;",com_spec) $ nod_nam = f$trnlnm("SYS$NODE") - "::" $ nod_nam = f$getsyi("SCSsystemID") $ $ if f$search(dat_spec) .eqs. "" $ then put "% Node list file not found (''dat_spec')" $ goto Common_exit $ endif $ $!-- Set up ERROR handler -- $ $ on control then goto Reset_exit $ $!-- Set terminal in NO-ECHO mode to avoid echoing of passwords -- $ $ if p1 .eqs. "" then set terminal/noecho $ $!-- Get CURRENT Password -- $ $ read/end=Reset_exit/err=Reset_exit /prompt="* Enter Current Password [Exit]: " sys$command cur_pw $ put "" ! NOECHO does not echo $ if cur_pw .eqs. "" then goto Reset_exit $ $!-- Get NEW password -- $ $ read/end=Reset_exit/err=Reset_exit /prompt="* Enter New Password [Exit]: " sys$command new_pw $ put "" ! NOECHO does not echo $ if new_pw .eqs. "" then goto Reset_exit $ read/end=Reset_exit/err=Reset_exit /prompt="* Enter Verification [Exit]: " sys$command new_ver $ put "" ! NOECHO does not echo $ if f$edit(new_pw,"upcase") .nes. f$edit(new_ver,"upcase") then goto Reset_exit $ write sys$output "The New Password is ", f$length(new_pw), " chars long." $ write sys$output " " $ $!-- Reset terminal echo -- $ $ set terminal/echo $ $!-- SURE ? -- $ $ read/end=Common_exit/err=Common_exit /prompt="* Are you sure? (Y/N) [N]: " sys$command q $ q = f$edit(q,"UPCASE,TRIM") $ if .not. q then goto Common_exit $ $!-- Create command file to be executed remotely -- $ $ if f$trnlnm("tmp_fil") .nes. "" then close tmp_fil $ open/write/err=tmp_err tmp_fil 'tmp_spec $ write/err=tmp_err tmp_fil "$ SET PASSWORD" $ write/err=tmp_err tmp_fil cur_pw $ write/err=tmp_err tmp_fil new_pw $ write/err=tmp_err tmp_fil new_pw $ close tmp_fil $ $!-- Set protection OK -- $ $ set file/pro=w:re 'tmp_spec $ $!-- Now process the NODENAME / USERNAME file -- $! This file contains one record per account on the remote system(s) $! Blank records and comment records (!) will be ignored $! Record the status in the LOG file. $ $ if f$trnlnm("dat_fil") .nes. "" then close dat_fil $ open/read/err=dat_err dat_fil 'dat_spec $ if f$trnlnm("log_fil") .nes. "" then close log_fil $ open/write/err=log_err log_fil 'log_spec $Dat_read: $ read/end=dat_end/err=dat_err dat_fil dat_rec $ wrk_rec = f$edit(dat_rec,"TRIM,COMPRESS,UNCOMMENT,UPCASE") $ if wrk_rec .eqs. "" then goto Dat_read $ rem_node = f$element(0," ",wrk_rec) $ rem_user = f$element(1," ",wrk_rec) $ gosub Request_function $ goto dat_read $Dat_end: $ close dat_fil $ close log_fil $ delete 'tmp_spec $ goto Common_exit $ $ $Request_function: $ put f$fao("!75*-") $ put "Processing user ''rem_user' on node ''rem_node' now" $ put "" $ log "" $ log "Processing user ''rem_user' on node ''rem_node' ",f$time() $ $ put "Copying procedure to ''rem_node'..." $ target := "''rem_node'""''rem_user' ''cur_pw'""::" $ copy/log /replace 'com_spec 'target $ sts = $status $ if .not. sts $ then log "% Error copying procedure" $ log f$message(sts) $ return $ endif $ $ put "Requesting execution..." $ if f$trnlnm("REM_FIL") .nes. "" then close rem_fil $ rem_spec := "''rem_node'""''rem_user' ''cur_pw'""::""0=''com_nam'""" $ open/read/write/err=Request_err rem_fil 'rem_spec $ write/err=Request_err rem_fil "''nod_nam'""""::''tmp_spec'" $ read/err=Request_err rem_fil sts $ close rem_fil $ put "Remote exec status = ",sts $ put f$message(sts) $ log "Remote exec status = ",f$message(sts) $ $ put "Cleaning up files..." $ target := "''rem_node'""''rem_user' ''new_pw'""::" $ delete/log 'target''com_nam'.com;* $ sts = $status $ if .not. sts $ then log "% Error when cleaning up procedure" $ log f$message(sts) $ endif $ $ put "" $ return $Request_err: $ sts = $status $ put "% Request error on node ''rem_node'" $ put f$message(sts) $ return $ $!---------------------------------------------------------------------------- ------------------------ $! $! This part of the code executes on the remote node (EXECUTOR) only $! $ $Execute_function: $ set noverify $ open/read/write/err=rem_err rem_fil SYS$NET $ read/end=Execute_end rem_fil tmp_spec $ @'tmp_spec $ write rem_fil $status $ close rem_fil $Execute_end: $ goto Common_exit $ $!---------------------------------------------------------------------------- ------------------------ $! $! This part is common for the entire procedure where executed by the REQUESTOR or EXECUTOR $! It contains the error routines and exit handlers $ $Dat_err: $ sts = $status $ put "% IO-error on ",dat_spec $ exit sts + (0*f$verify(verify_context)) $Log_err: $ sts = $status $ put "% IO-error on ",log_spec $ exit sts + (0*f$verify(verify_context)) $Rem_err: $ sts = $status $ put "% IO-error on ",Rem_node $ exit sts + (0*f$verify(verify_context)) $Tmp_err: $ sts = $status $ put "% IO-error on ",Tmp_spec $ exit sts + (0*f$verify(verify_context)) $Reset_exit: $ set terminal/echo $Common_exit: $ exit $status + (0*f$verify(verify_context)) o / o / o / o / -----------------X---------------X---------------X---------------X---- o \ o \ o \ o \ -------------------------------------------------------------------------- Sheldon E. Smith ! Sheldon.Smith@MPO.MTS.DEC.com Systems Integration Dept. ! (612) 851-2254 / DTN 442-2254 Digital Equipment Corporation ! Minneapolis, Minnesota ========================================================================== http://altavista.digital.com/ Alta Vista: The Largest Web Index!