From:	US2RMC::"""APACHE::HESTERMANS""@mesaii.trw.com" "I think, there for I think I am. I think..."  4-AUG-1995 04:42:55.96
To:	OPEN-VMS-SIG@decus.org
CC:	
Subj:	SET UIC from a program

Nigel White wrote:

> We need a process to "assume" a user's identity in the same way as the
> Unix setuid() system call allows. We are writing a fileserver, in which
> the serving process is privileged, but must honour the protections of
> the username the client is using.
> 
> There is no system service (Yet) which does this, and I was told that DECUS
> has example programs which use the same technique as DCL. We are writing in
> C, please could you email me some code examples of how to change a
> process's UIC.

I don't know about DECUS submissions, but here is a sample C program.

      ***************************************************************
      Please note that any time you write KERNEL mode code, you risk
      crashing the system!
      ***************************************************************


------------------------------ Start of Make File ------------------------------
setuic.obj : setuic.c
       cc/nooptimize/debug setuic

setuic.exe : setuic.obj setuic.mak
       link/NOdebug/NOtrace  setuic
------------------------------- End of Make File -------------------------------


------------------------------ Start of SETUIC.C -------------------------------
#include stdio;
#include stdlib;

/* You need CMEXEC privilege to SEE your UIC.                     */
/* You need CMKRNL privilege to CHANGE your UIC.                  */
/*                                                                */
/* NOTICE:  CMKRNL will CRASH the system if ANYthing goes wrong!  */
/*   This includes PAGE FAULTS while in kernel mode.              */
/*   You should really consider locking down your working set     */
/*   or at least the kernel mode routine prior to executing it    */
/*                                                                */
/*   This example executed fine on my development system.         */
/*                                                                */
/*   I make no claims to its suitability for YOUR system!         */
/*                                                                */
/*                                                                */
/* %x7FFEFF58 obtained by $ SEARCH SYS$SYSTEM:SYS.MAP  CTL$GL_PCB */
/* Make sure this value hasn't changed on your system !!!         */
/* Converted to decimal here V   */
#define  CTL$GL_PCB  2147417944

/* %xC4 is a constant obtained from sys$system:sysdef.stb */
#define  PCB$L_UIC   196



int getuic( int *uicptr )
{
    int *pcbptr ;    /* point where base address of PCB is stored */
    int *pcbuicptr ; /* pointer to UIC in the PCB */

    pcbptr = CTL$GL_PCB ;             /* I didn't want to *a_constant      */
    pcbuicptr = *pcbptr + PCB$L_UIC ; /* add offset so we point at PCB UIC */

    *uicptr = *pcbuicptr ; /* copy PCB UIC into *uicptr */

    return 1;  /* signal success */
}



int setuic( int *uicptr )
{
    int *pcbptr ;    /* point where base address of PCB is stored */
    int *pcbuicptr ; /* pointer to UIC in the PCB */

    pcbptr = CTL$GL_PCB ;             /* I didn't want to *a_constant      */
    pcbuicptr = *pcbptr + PCB$L_UIC ; /* add offset so we point at PCB UIC */

    *pcbuicptr = *uicptr ; /* copy *uicptr into PCB UIC */

    return 1;  /* signal success */
}



int main()

{
  int stat = 1 ;
  struct  {                          /* Group / member format  */
             unsigned short mem ;    /* Member number          */
             unsigned short grp ;    /* Group number           */
          } uic;
 
  struct  {  int count ;
             int *ptr ;
          } arglist;



    arglist.count = 1 ;
    arglist.ptr = &uic ;


    /* This step is here mainly as an example of getting your UIC.  */
    /* It is not required in order to change your UIC.              */

    stat = SYS$CMEXEC( getuic , &arglist );
    printf( "Old UIC: [%o,%o]\n" ,  uic.grp , uic.mem );




    /* Set these to your desired values for the NEW UIC  */

    uic.grp =  100 ;
    uic.mem =  200 ;

    stat = SYS$CMKRNL( setuic , &arglist );
    /* if you get this far without crashing VMS, you have done well! */

    printf( "New UIC: [%o,%o]\n" ,  uic.grp , uic.mem );

    return stat ;
}
------------------------------- End of SETUIC.C --------------------------------

% ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ======
% Received: from mail1.digital.com by us2rmc.zko.dec.com (5.65/rmc-22feb94) id AA17949; Fri, 4 Aug 95 04:27:33 -040
% Received: from Topaz.DECUS.Org by mail1.digital.com; (5.65 EXP 4/12/95 for V3.2/1.0/WV) id AA32538; Fri, 4 Aug 1995 01:20:26 -070
% Received: from Reprocess.DECUS.Org by DECUS.Org (PMDF V4.2-13 #9698) id <01HTNQTT5H5C9356FN@DECUS.Org>; Fri, 4 Aug 1995 02:35:04 ED
% Received: from linus (mesaii.trw.com) by DECUS.Org (PMDF V4.2-13 #9698) id <01HTNQTO8NEO935AUW@DECUS.Org>; Fri, 4 Aug 1995 02:34:55 ED
% Date: Thu, 03 Aug 1995 23:31:30 -0700
% From: "APACHE::HESTERMANS"@mesaii.trw.com (I think, there for I think I am. I think...
% Subject: SET UIC from a program
% To: OPEN-VMS-SIG@decus.org
% Errors-To: open-vms-sig-owner@DECUS.Org
% Warnings-To: open-vms-sig-owner@DECUS.Org
% Message-Id: <95080323312995@linus.mesaii.trw.com>
% X-Vms-To: VMSSIG
% X-Vms-Cc: SELF
% Content-Transfer-Encoding: 7BIT
% Comments: Send OPEN-VMS-SIG subscribe/unsubscribe requests to mailserv@DECUS.Org
