From:	AITGW::"timcc%CSV.VICCOL.EDU.AU@VM1.NoDak.EDU" 16-DEC-1991 03:54:47.46
To:	Multiple recipients of list ANU-NEWS <ANU-NEWS@NDSUVM1>
CC:	
Subj:	Fix: VMS NEWS looks at wrong rights list

Received: by AITGW.DECnet (utk-mail11 v1.5) ; Mon, 16 Dec 91 03:52:35 EST
Received: from vm1.NoDak.edu by aitgw.ge.com (5.65/GE Gateway 1.4)
	id AA07469; Mon, 16 Dec 91 03:52:24 -0500
Message-Id: <9112160852.AA07469@aitgw.ge.com>
Received: from NDSUVM1.BITNET by VM1.NoDak.EDU (IBM VM SMTP R1.2.1MX) with BSMTP id 9418; Mon, 16 Dec 91 02:52:09 CST
Received: from NDSUVM1.BITNET by NDSUVM1.BITNET (Mailer R2.07) with BSMTP id
 0172; Mon, 16 Dec 91 02:52:08 CST
Date:         Mon, 16 Dec 1991 22:10:12 GMT
Reply-To: timcc%CSV.VICCOL.EDU.AU@VM1.NoDak.EDU
Sender: ANU-NEWS Discussion <ANU-NEWS@VM1.NoDak.EDU>
From: timcc%CSV.VICCOL.EDU.AU@VM1.NoDak.EDU
Subject:      Fix: VMS NEWS looks at wrong rights list
To: Multiple recipients of list ANU-NEWS <ANU-NEWS@NDSUVM1>
 
(Explanation:  I came up with this because our translation of
NEWS_NONETPOST is granted to users dynamically at login time based on
specific account details.)
 
VMS NEWS has several features that require authorization.  This
authorization is controlled using VMS rights identifiers.  Unfortunately,
VMS NEWS looks up a process' rights using SYS$FIND_HELD, which only returns
those rights identifiers the user is granted via the system rights
database.
 
A VMS process can hold more, less, or a totally different set of rights at
any time during its execution, therefore VMS NEWS should be doing its
authorization checks using the process rights list.  The process rights
list is obtained using the JPI$_RIGHTSLIST item of the SYS$GETJPI system
call.
 
A patch to NEWSSITE.C to facilitate this proper behaviour is included
below.  It is based on the V6.0-3 version.
 
 
*** newssite.c-dist
--- newssite.c
**************
*** 31,36
  #include psldef
  #include syidef
  #include uaidef
  #else
  #include <lnmdef.h>
  #include <psldef.h>
--- 31,37 -----
  #include psldef
  #include syidef
  #include uaidef
+ #include jpidef
  #else
  #include <lnmdef.h>
  #include <psldef.h>
**************
*** 36,41
  #include <psldef.h>
  #include <syidef.h>
  #include <uaidef.h>
  #endif
 
  #ifndef UAI$V_RESTRICTED
--- 37,43 -----
  #include <psldef.h>
  #include <syidef.h>
  #include <uaidef.h>
+ #include <jpidef.h>
  #endif
 
  #ifndef UAI$V_RESTRICTED
**************
*** 256,262
 
  no_priv()
  {
!   int mgr_id, id = 0, attribs = 0, contxt = 0, lstatus, idindx, mem_sysprv;
    unsigned int holder[2];
 
    if (mgr_priv != -1) return(mgr_priv);
--- 258,264 -----
 
  no_priv()
  {
!   int mgr_id, id = 0, contxt = 0, lstatus, idindx, mem_sysprv;
    unsigned int holder[2];
 
  /*
**************
*** 259,264
    int mgr_id, id = 0, attribs = 0, contxt = 0, lstatus, idindx, mem_sysprv;
    unsigned int holder[2];
 
    if (mgr_priv != -1) return(mgr_priv);
    if (mem_sysprv = sysprv_off) sysprv();
    if (!*mgrid) mgr_id = -1;
--- 261,295 -----
    int mgr_id, id = 0, contxt = 0, lstatus, idindx, mem_sysprv;
    unsigned int holder[2];
 
+ /*
+  * If we have a version of VMS that does not know about the JPI$_RIGHTSLIST
+  * item, we better not try and use it...
+  */
+ #ifndef JPI$_RIGHTSLIST
+ #define ORIGINAL_no_priv
+ #endif
+
+ #ifndef ORIGINAL_no_priv
+   struct id_attr {
+      unsigned long identifier ;
+      unsigned long attributes ;
+      } ;
+   struct id_attr held_id_attr[99] ;
+
+   /* Length of binary rights list array, in bytes */
+   unsigned short jpi_return_length ;
+
+   struct item_list {
+     unsigned short buffer_length ;
+     unsigned short item_code ;
+     void *buffer_address ;
+     void *return_length_address ;
+     unsigned long terminator ;
+     } jpi_item_list = {sizeof (held_id_attr), JPI$_RIGHTSLIST,
+                        (void *) held_id_attr, (void *) &jpi_return_length, 0};
+
+ #endif
+
    if (mgr_priv != -1) return(mgr_priv);
    if (mem_sysprv = sysprv_off) sysprv();
    if (!*mgrid) mgr_id = -1;
**************
*** 263,268
    if (mem_sysprv = sysprv_off) sysprv();
    if (!*mgrid) mgr_id = -1;
    else if (!(sys$asctoid(c$dsc(mgrid),&mgr_id,0) & 1)) mgr_id = -1;
    holder[0] = (getgid() << 16) + getuid();
    holder[1] = 0;
    idindx = 0;
--- 294,301 -----
    if (mem_sysprv = sysprv_off) sysprv();
    if (!*mgrid) mgr_id = -1;
    else if (!(sys$asctoid(c$dsc(mgrid),&mgr_id,0) & 1)) mgr_id = -1;
+
+ #ifdef ORIGINAL_no_priv
    holder[0] = (getgid() << 16) + getuid();
    holder[1] = 0;
    idindx = 0;
**************
*** 266,271
    holder[0] = (getgid() << 16) + getuid();
    holder[1] = 0;
    idindx = 0;
    mgr_priv = 1;
    while ((lstatus = sys$find_held(holder,&id,&attribs,&contxt)) & 1) {
      held_ids[idindx++] = id;
--- 299,306 -----
    holder[0] = (getgid() << 16) + getuid();
    holder[1] = 0;
    idindx = 0;
+ #endif
+
    mgr_priv = 1;
 
    /*
**************
*** 267,273
    holder[1] = 0;
    idindx = 0;
    mgr_priv = 1;
!   while ((lstatus = sys$find_held(holder,&id,&attribs,&contxt)) & 1) {
      held_ids[idindx++] = id;
      if (id == mgr_id) mgr_priv = 0;
      }
--- 302,317 -----
  #endif
 
    mgr_priv = 1;
!
!   /*
!    * SYS$FIND_HELD looks up the RIGHTSLIST database for identifiers held.
!    * What is more relevant is the list of rights identifiers currently held by
!    * the process, which can be obtained using the JPI$_RIGHTSLIST item of the
!    * SYS$GETJPI system call.
!    */
!
! #ifdef ORIGINAL_no_priv
!   while ((lstatus = sys$find_held(holder,&id,0,&contxt)) & 1) {
      held_ids[idindx++] = id;
      if (id == mgr_id) mgr_priv = 0;
      }
**************
*** 273,278
      }
    held_ids[idindx] = 0;
    sys$finish_rdb(&contxt);
    if (mem_sysprv) nosysprv();
    return(mgr_priv);
  }
--- 317,335 -----
      }
    held_ids[idindx] = 0;
    sys$finish_rdb(&contxt);
+ #else
+
+   if (sys$getjpiw (0,0,0,&jpi_item_list,0,0,0) & 1) {
+     int ident_count = jpi_return_length / sizeof (struct id_attr);
+
+     held_ids[ident_count] = 0;
+     while (--ident_count >= 0) {
+       held_ids[ident_count] = held_id_attr[ident_count].identifier;
+       if (held_ids[ident_count] == mgr_id) mgr_priv = 0;
+       }
+     }
+ #endif
+
    if (mem_sysprv) nosysprv();
    return(mgr_priv);
  }
