Operating System - OpenVMS
1828484 Members
2805 Online
109978 Solutions
New Discussion

Re: Help writing a com file

 
SOLVED
Go to solution
vmsserbo
Super Advisor

Help writing a com file

I need to put together a SPECIAL_SUB procedure to parse out the ENQLM of ALL our accounts nationwide and return a list of those with 32767 or greater (including our system-level accounts.)


Can someone help me to write a simple com file so I can use it on all of our 90+ nodes? Is it as simple as that? Your help would be greatly appreciated!

32 REPLIES 32
Jess Goodman
Esteemed Contributor
Solution

Re: Help writing a com file

I would use the freeware package SCANUAF. It can search multiple SYSUAF.DATs for user fields <,=,> to a given value.
I have one, but it's personal.
vmsserbo
Super Advisor

Re: Help writing a com file

Isn't there a simple dcl procedure that someone could write to do these things and execute them ?

Peter Zeiszler
Trusted Contributor

Re: Help writing a com file

I would suggest looking into using the GETUAI tool. You could then call each account and evaluate the output.

Another simple way could also be to do the following search:
mc authorize list */full
sea sysuaf.lis username,Enqlm

That output then has the Username and Enqlm values. You could output the data to a file and read 2 lines at a time. Then use string manipulations to pull out the values on enqlm > 32767.

Quick example:
mc authorize list */full
sea sysuaf.lis username,Enqlm/out=x.x

Create file: x.com
$ set noon
$ open/read/err=close_file in_file x.x
$Next_record:
$ read/end_of_file=close_files in_file user_rec
$ read/end_of_file=close_files in_file record1
enq = f$element(3," ",f$edit(record1,"compress"))
$ if enq .ge. 32767
$ then
$ username = f$element(1," ",f$edit(user_rec,"compress"))
$ write sys$output "''username' - ''enq'"
$ goto next_record
$!
$close_files:
$ close in_file
$ exit
vmsserbo
Super Advisor

Re: Help writing a com file

Can you be more speific? Sorry I am still learning.

I created a come file called enqlm_fix.com

$ set noon
$ open/read/err=close_file in_file x.x
$ Next_record:
$ read/end_of_file=close_files in_file user_rec
$ read/end_of_file=close_files in_file record1
enq = f$element(3," ",f$edit(record1,"compress"))
$ if enq .ge. 32767
$ then
$ username = f$element(1," ",f$edit(user_rec,"compress"))
$ write sys$output "''username' - ''enq'"
$ goto next_record
$!
$close_files:
$ close in_file
$ exit

What file name do I put in for the x.x

Also, when I am done can I run it and how?
If this works I plan to copy thos to all our nodes?
vmsserbo
Super Advisor

Re: Help writing a com file

The in_file x.x is the output file I created when I did the search. Is that correct?

Once I finish do I do an @enqlm_fix.com
or a submit?

vmsserbo
Super Advisor

Re: Help writing a com file

Hello,

Here is what I did on our Test Server.

In my home directory USRDSK1:[BLS]
I did a mc authorize list */full
Which produced a sysuaf.lis

Directory DUA1:[BLS]
SYSUAF.LIS;1 201/210 9-AUG-2006 15:24

Then I did a:
sea sysuaf.lis username,Enqlm/out=x.x
Which produced a x.x file in my home directory as well

I created a come file called enqlm_fix.com
which is also in my home directory as well.

typ enqlm_fix.com
$ set noon
$ open/read/err=close_file in_file x.x
$ Next_record:
$ read/end_of_file=close_files in_file user_rec
$ read/end_of_file=close_files in_file record1
enq = f$element(3," ",f$edit(record1,"compress"))
$ if enq .ge. 32767
$ then
$ username = f$element(1," ",f$edit(user_rec,"compress"))
$ write sys$output "''username' - ''enq'"
$ goto next_record
$!
$close_files:
$ close in_file
$ exit

Now, what do I do? Do I @enqlm_fix.com

or submit it?

Let me know!

Thanks!




Dale A. Marcy
Trusted Contributor

Re: Help writing a com file

Miles,

Welcome to VMS. Since nobody has replied yet. I will try to answer your last question:

"Once I finish do I do an @enqlm_fix.com or a submit?"

You can execute it either way. The way the command procedure is currently written, it will expect the file X.X to be in the default directory. You can combine the external commands into the command procedure as follows:

$ set noon
$ mc authorize list */full
$ sea sysuaf.lis username,Enqlm/out=x.x
$ open/read/err=close_file in_file x.x
$ Next_record:
$ read/end_of_file=close_files in_file user_rec
$ read/end_of_file=close_files in_file record1
$ enq = f$element(3," ",f$edit(record1,"compress"))
$ if enq .ge. 32767
$ then
$ username = f$element(1," ",f$edit(user_rec,"compress"))
$ write sys$output "''username' - ''enq'"
$ goto next_record
$!
$close_files:
$ close in_file
$ exit

If you submit the procedure, then the output will be in the log file. By default it is created in the Sys$Login directory of the user with the same name as the command procedure and an extension of .Log. If you wish to direct it elsewhere or change the name, you can specify /Log=disk:[directory]filename.ext on the submit command.

Hope this helps.
vmsserbo
Super Advisor

Re: Help writing a com file

Fantastic! Thanks! I will try it now!

vmsserbo
Super Advisor

Re: Help writing a com file

Sorry,

One more question? What will this com file do exactly? Is it going to chane the values of the enqlm or just do a listing?

Thanks again!
Dale A. Marcy
Trusted Contributor

Re: Help writing a com file

It will just give a listing of usernames and enqlm where the enqlm is greater than the 32767.
vmsserbo
Super Advisor

Re: Help writing a com file

Oh,

I think I am missing an else in the command procedure? Where does that go?

$ set noon
$ mc authorize list */full
$ sea sysuaf.lis username,32767/out=x.x
$ open/read/err=close_file in_file x.x
$ Next_record:
$ read/end_of_file=close_files in_file user_rec
$ read/end_of_file=close_files in_file record1
$ enq = f$element(3," ",f$edit(record1,"compress"))
$ if enq .ge. 32767
$ then
$ username = f$element(1," ",f$edit(user_rec,"compress"))
$ write sys$output "''username' - ''enq'"
$ goto next_record
$!
$ close_files:
$ close in_file
$ exit
Dale A. Marcy
Trusted Contributor

Re: Help writing a com file

Actually, it was an endif that was missing. I have inserted it in the code below and indented the lines between the if and endif.

$ set noon
$ mc authorize list */full
$ sea sysuaf.lis username,32767/out=x.x
$ open/read/err=close_file in_file x.x
$ Next_record:
$ read/end_of_file=close_files in_file user_rec
$ read/end_of_file=close_files in_file record1
$ enq = f$element(3," ",f$edit(record1,"compress"))
$ if enq .ge. 32767
$ then
$ username = f$element(1," ",f$edit(user_rec,"compress"))
$ write sys$output "''username' - ''enq'"
$ endif
$ goto next_record
$!
$ close_files:
$ close in_file
$ exit
John Gillings
Honored Contributor

Re: Help writing a com file

Miles,

> What will this com file do exactly?

It will parse your SYSUAF listing and reveal the usernames with ENQLM = 32767

No offence intended, but if you can't work that out, you really shouldn't be downloading random command procedures from strangers and executing them. Especially from privileged accounts when the apparent purpose is to manipulate authorization data. Who knows what they might do?

I'd suggest rather than writing command procedures for such a specific request, you find a more generic solution to your overall issue of user management. For example, if you have 90+ nodes, perhaps you should be using the OpenVMS Management Station to manage your users? A nice GUI interface which can potentially show you all your users across all systems in one window. I think the version I'm using is fairly old - it can sort users on various fields, maybe a later one can do it on ENQLM?

Another option is to export your UAF data into a CSV file, then you can load it into Excel, sort on ENQLM, and you've answered your specific question easily. You can also answer a huge variety of similar questions, without having to write another procedure.
A google search "SYSUAF EXCEL" will quickly find several possibilities.
A crucible of informative mistakes
vmsserbo
Super Advisor

Re: Help writing a com file

Thanks for all your help. Just one more question. How do I parse all those output file I created from all of our nodes into one file.

I have about 70 file here is an example

TEAM07_ENQLM_32767.DOC
TEAM08_ENQLM_32767.DOC
NASHVI_ENQLM_32767.DOC
ETC...

I know how to append them to one file, the problem is, how do I include the node names for each file in the appended file. What I will have is a list like this. Here is an example

Username: SIKORSKIK Owner:
Username: SOLLERSD Owner:
Username: SQLSRV$SRV Owner:
Username: SUPUSER Owner:
Username: SYSTEM Owner: SYSTEM MANAGER
CPU: (none) Enqlm: 32767 Pgflquo: 750000
Username: SYSTEST Owner: SYSTEST-UETP
Username: SYSTEST_CLIG Owner: SYSTEST-UETP
Username: SYS_ANDYW Owner: Sys - Andy Winter
CPU: (none) Enqlm: 32767 Pgflquo: 750000
Username: SYS_DAVIDP Owner: Sys - David Plowman
CPU: (none) Enqlm: 32767 Pgflquo: 750000
Username: SYS_KURTH Owner: Sys - Kurt Hyde
CPU: (none) Enqlm: 32767 Pgflquo: 750000
Username: SYS_MILESO Owner: Sys - Miles Ostojic
CPU: (none) Enqlm: 32767 Pgflquo: 750000
Username: SYS_PAULP Owner: Sys - Paul Putong
CPU: (none) Enqlm: 32767 Pgflquo: 750000
Username: SYS_STEVEO Owner: Sys - Steve Olson
CPU: (none) Enqlm: 32767 Pgflquo: 750000
Username: TAYLORE Owner:
Username: UPLOAD Owner:

This doesn't give the name of the Node???

vmsserbo
Super Advisor

Re: Help writing a com file

Okay, I got a listing in one file. It is attached. Now what I have to do is the following:

I need to bump them down. They should at least be bumped down to (value-1).

Do I have to login eacf of our systems and do this manually or is there a quicker and better way to do this?

vmsserbo
Super Advisor

Re: Help writing a com file

I know the command to chage the enqlm is

mcr authorize
modify sys_miles/enqlm=32766

How do I automate this to execute on all nodes without having to login on every node and doing this command manually?

Volker Halle
Honored Contributor

Re: Help writing a com file

Miles,

you could write DCL procedures for each node, which contain the necessary MODIFY user/ENQLM=nnn commands for each user on that node. You can generate those .COM files from your user listing.

You can then COPY these command files to each individual node and use SUBMIT/REMOTE to submit that command file to the SYS$BATCH queue on that node.

Example: xxx_ENQLM.COM (for node XXX)

$ SET DEF SYS$SYSTEM
$ RUN AUTHORIZE
MOD user1/ENQLM=32766
MOD user2/ENQLM=32766
$ EXIT

$ COPY xxx_enqlm.com xxx"priv_user pwd"::
$ SUBMIT/REMOTE xx"priv_user pwd"::xxx_ENQLM.COM

If appropriate DECnet proxies have been set up on the remote nodes, you could do all that without having to provide username/pwd.

Volker.
Hein van den Heuvel
Honored Contributor

Re: Help writing a com file

You should know what mechanisme you have to start something on the other nodes (decnet task, batch job, management console software, plop a file in an NFS direcory, whatever).
Probably the same mechanisme you used to get the data.

Now I would create a DCL or PERL script to read the list you attached and generated a script for each node.

In perl that would be something like:

$create per_node.pl
use strict;
use warnings;

my ($node,$user, $enq, $file, %files, %records);

while (<>) {
($node,$user, $enq) = split /\s+-\s+/;
if ($enq) {
if (!defined ($files{$node})) {
$file = $node . ".tmp";
open $files{$node}, ">$node.tmp" or die "could not create $file";
print {$files{$node}} "MCR AUTORIZE\n";
}
$records{$node}++;
$enq--;
print {$files{$node}} "MODIFY $user/ENQL=$enq\n";
}
}
$enq = 0;
foreach $node (sort keys %files) {
close $files{$node};
print "Node $node, $records{$node} records.\n";
$enq++;
}
print "$enq scripts generated.\n";
$
$perl per_node.pl all_nodes_all_users.txt
:
:
Node VANCOU, 28 records.
Node VENTUR, 28 records.
Node VISALI, 28 records.
Node WASHIN, 28 records.
Node WHITEP, 28 records.
68 scripts generated.

btw 1....

You can run that script on your windoze or unix box if your VMS system does not (yet) have perl. I did! :-)

btw 2....

In perl it would be trival to make sure the ENQ was the same for the same username (min or max) accross all nodes.
As you read, only remember node-user combos and remember the max(enq) for each unique user.
When all is read cull the data from the array and write the output files.


Enjoy,
Hein.
Robert Brooks_1
Honored Contributor

Re: Help writing a com file

You've gotten decent information on how to perform your task.

I'm interested in knowing *why* you are interested in dealing with ENQLM. What problem are you trying to solve?

(I am aware of some potential reasons, and why you may be interested specifically in accounts where ENQLM >= 32767, but I'd like to hear what misbehaviour you have observed).

-- Rob
vmsserbo
Super Advisor

Re: Help writing a com file

To answer your question on why I feel we should lower the ENQLM>

Every now and then, we experience some bugcheck dumps where the users are exceeding their ENQLM.
Jan van den Ende
Honored Contributor

Re: Help writing a com file

Miles,

as I understand, you are trying to LOWER the ENQLM values.
At least two issues that I see with that:
1- IF any of those nodes has SYSGEN param PQL_MENQLM value higher than what you want to screw down to, the PQL value will take precedence.
2- (at least some of) these accounts have (had?) a reason to have this value.
If you lower them indiscriminatingly, you _MIGHT_ run into applications that after the change do not run anymore, or behave unexpectedly!

I do understand that there may perfectly valid reasons to want this change, but I like you to at least be aware of potential possible negative consequences!

Proost.

Have one on me.

jpe
Don't rust yours pelled jacker to fine doll missed aches.
Hein van den Heuvel
Honored Contributor

Re: Help writing a com file

Here... for grins... the other approach where you make the ENQLM for a given user the same accross all nodes (right or wrong!)


use strict;
use warnings;

my ($node, $user, $old_node, $nodes, $old_enq, %users, %records, %max);

while (<>) {
# if (/($S+)\s+-\s+($S+)\s+-\s+(\d+)/)
my ($node, $user, $enq) = split /\s+-\s+/;
if ($enq) {
$old_enq = $users{"$node:$user"};
if (!defined($old_enq) || $old_enq < $enq) {
$users{"$node:$user"} = $enq;
$max{$user} = $node;
$records{$node}++;
}
}
}
$old_node = "";
foreach (sort keys %users) {
($node, $user) = split /:/;
my $enq = $users{"$node:$user"} - 1;
unless ($node eq $old_node) {
$nodes++;
if ($old_node) {
close TMP;
print "Node $old_node, $records{$node} records.\n";
}
my $file = $node . ".tmp";
$old_node = $node;
open TMP, ">$node.tmp" or die "could not create $file";
print TMP "\$MCR AUTHORIZE\n";
}
printf TMP "MODIFY %-12s/ENQL=%-5d !From node %s\n",
$user, $enq, $max{$user};
}
print "Node $old_node, $records{$node} records.\n";
close TMP;
print "$nodes scripts generated.\n";


:

type TEAM08.tmp
$MCR AUTHORIZE
MODIFY APP_BRIANZ /ENQL=32766 !From node WHITEP
:
MODIFY DEV_ANDYM /ENQL=32766 !From node WHITEP
MODIFY DEV_BRIANB /ENQL=32766 !From node TEAM09
MODIFY DEV_CELESTEP/ENQL=32766 !From node WHITEP

Robert Brooks_1
Honored Contributor

Re: Help writing a com file

Miles wrote . . .

Every now and then, we experience some bugcheck dumps where the users are exceeding their ENQLM.

----

Do you mean system crashes, or process crashes?

Can you explain how you came to your conclusion regarding cause and effect?

Why are you keying in on users with an ENQLM of 32767 or greater?

What version of VMS?

-- Rob
John Gillings
Honored Contributor

Re: Help writing a com file

Miles,

Please look at the OpenVMS Management Station. You can add all your nodes and manage them all from a single GUI interface. In this case you could select ALL your users across ALL nodes, click "properties", fo to the QUOTAS pane and set the ENQLM for every user with one mouse click.

The software is installed, and licensed with OpenVMS. To start it on the VMS systems, include SYS$STARTUP:TNT$STARTUP.COM in your system startup. For the PC interface, copy the file SYS$SYSROOT:[TNT.CLIENT]TNT*.EXE to a PC and execute it to install.

You then need to add each cluster or node.
A crucible of informative mistakes