[comp.os.vms] Any success with $SETUAI?

vsmith@instr.camosun.bcc.CDN (Vaughn Smith) (06/19/87)

> Second:  In my opinion, which you may choose to ignore or not, having a
> *system service* to muck with the UAF is stupid.  I can only see two reasons
> for having it:  1> So that you can have "group managers" who can bash their
> underlings' accounts,

We would like to use $SETUAI so that students could set the owner field on 
their accounts when they log in for the first time. The old program to do
this requires changing every time VMS changes the UAF. We get the following
on both VMS 4.4 and VMS 4.5A (LAVC):

%RMS-F-RNL, record not locked
%TRACE-F-TRACEBACK, symbolic stack dump follows
module name     routine name                     line       rel PC    abs PC
SETUAI$MAIN     SETUAI$MAIN                       195      0000005D  0000065D


Shouldn't the system service return an error and not leave it to RMS? The 
documentation on $SETUAI looks like too much like $GETUAI.

Thanks in advance.
Vaughn Smith.

carl@CITHEX.CALTECH.EDU.UUCP (06/19/87)

>  We would like to use $SETUAI so that students could set the owner field  on
>  their  accounts when they log in for the first time.  The old program to do
>  this requires changing  every  time  VMS  changes  the  UAF.   We  get  the
>  following on both VMS 4.4 and VMS 4.5A (LAVC):

>  %RMS-F-RNL, record not locked
>  %TRACE-F-TRACEBACK, symbolic stack dump follows
>  module name     routine name                     line       rel PC    abs PC
>  SETUAI$MAIN     SETUAI$MAIN                       195      0000005D  0000065D

>  Shouldn't the system service return an error and not leave it to RMS?   The
>  documentation on $SETUAI looks like too much like $GETUAI.

I had started out to say:
 I't really hard to diagnose your problem when you don't  include  any  of  the
 relevent code; however I CAN tell you a) What the error message you're getting
 means; and b) That YOU must be doing something wrong, since $SETUAI does work.

 The error message "%RMS-F-RNL, record not locked" means that you're trying  to
 update  a record in a file (that is to say, a record with the same key [for an
 indexed file] or at the same address [for a file  opened  for  direct  access]
 already  exists  and  you want to replace the old version with a new one), but
 you either haven't read the record, or you read it without  locking  it.   Are
 you  sure  you're  trying to modify the OWNER field and not, say, the USERNAME
 field?

But while I was testing my program, I suddenly found myself getting  the  same
error  message  (even  though the program had worked several times before).  A
comparison of the situation in which the program worked and that in  which  it
failed  show that it had to be a privilege problem:  I had TOO MANY privileges
set.  So, starting with all privileges set, I began throwing away a few  at  a
time,  until I tracked down the culprit:  GRPPRV.  The bug shows up after it's
been determined that you have write  access  to  SYSUAF.DAT,  but  before  the
record  is updated, and I'm not expecting to pin it down any more closely than
that (Frankly, I'd be scared to try.  Someone asked in this  teleconference  a
couple  of  days ago where the next security hole would come from.  Given that
$SETUAI is STILL definitely NOT functioning as it was intended to, I  wouldn't
be surprised to find a hole related to this problem).

At any rate, the problem's not in your code, it's in the system  service,  and
since  I've  taken  the  trouble to write a short demonstration program (in C)
that changes the OWNER field in SYSUAF, I might as well post it:

/*   SET_PERSONAL_NAME - modify the OWNER field in SYSUAF.DAT via $SETUAI   */
#include descrip
#define UAI$_OWNER	0x0000000C

struct dsc$descriptor *dsc(string)
char *string;
{   static struct dsc$descriptor d = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};

    d.dsc$w_length = strlen(string);
    d.dsc$a_pointer = string;
    return(&d);
}

main(nargs, args)
int nargs;
char **args;
{	extern long SYS$SETUAI();
	long status;
	static char owner[32];
	struct  ITMLST_3
		{	short buffer_length;
			short item_code;
			char *buffer_address;
			short *return_length_address;
		} itmlst[2] = {{32, UAI$_OWNER, owner, 0},
			       { 0,          0,     0, 0}};

	if (nargs != 3)
	{	puts("Usage: SET_PERSONAL_NAME personalname username");
		exit(1);
	}
	*owner = strlen(*++args);
	if(*owner < 32)
		strcpy(owner + 1, *args);
	else
	{	puts("You personal name must be less than 32 bytes long.");
		exit(1);
	}
	exit(SYS$SETUAI(0,0,dsc(*++args),itmlst,0,0,0));
}