From - Mon Oct 27 08:39:31 1997
Path: news.mitre.org!blanket.mitre.org!agate!ihnp4.ucsd.edu!mvb.saic.com!nntprelay.mathworks.com!cam-news-hub1.bbnplanet.com!su-news-hub1.bbnplanet.com!news.bbnplanet.com!news1.digital.com!pa.dec.com!eps.enet.dec.c*m!vandenheuvel
From: vandenheuvel@eps.enet.dec.c*m (Hein RMS van den Heuvel)
Newsgroups: comp.os.vms
Subject: Re: Need help on UAF.EXE
Date: 25 OCT 97 23:48:01
Organization: Digital Equipment Corporation
Lines: 225
Message-ID: <62uf0h$4je@usenet.pa.dec.com>
References: <39751517@MVB.SAIC.COM> <SwHxqDhc5vt5@vmsmail.gov.bc.ca>
NNTP-Posting-Host: amuzed


In article <SwHxqDhc5vt5@vmsmail.gov.bc.ca>, Ed.Wilts@gems1.gov.bc.ca (Ed Wilts) writes...
>In article <39751517@MVB.SAIC.COM>, Paddy.O'Brien@TransGrid.nswgovgrid.telememo.au writes:
:
>Just to pick up where Paddy and Ferry missed.  UAF is a program from Joe
>Meadows to generate reports from the UAF.  It addresses some very important
>requirements that AUTHORIZE should address, but doesn't.  For example, have you
>ever tried to modify everyone's UAF record with a new minimum FILLM to run a

The man has a point. Ofcourse for the specific problem on hand one
could punt and set SYSGEN PQL_MFILLM to the new minimum, but AUTHORIZE
does have  a bunch of limitation. 
Within Digital someone recently wondered whether there was a tool to 
report SYSUAF info in CSV format. I hacked up the a tool overnight 
which I include here just in case other would see this as helpfull. 
[Sorry, but is only tested with VAXC on VMS V6.0 for now]

Cheers,
	Hein.

#include <descrip>
#include <uaidef>
#include <stdio>
#include <ctype>
#include <RMS>


/*  GETUAI.C,	Hein van den Heuvel, September 1997
**
**  Test program to extract SYSUAF data into comma seperated value (CSV) list.
**  Only tested using VAXC, the fao_param list use will need fixing for Alpha.
*/

typedef struct { short size, code; void *buf; short *len; } item;
typedef struct { short size, code; char *format, *name ;} field;
char *out_p, *fao_p, username[64];
$DESCRIPTOR	(username_d, username);

void setup_field ( field *f, item *i, char *buffer, void **fao_param )
{
    out_p += sprintf (out_p, "%s,",f->name);

    i->size =  f->size;
    i->code =  f->code;
    i->len =  NULL;
    strcpy (fao_p,   f->format);
    fao_p += strlen( f->format);
    	    
    if (f->size <= 4) {
	i->buf = (void *) fao_param;
	*fao_param = 0;
    } else {
	i->buf = buffer;
	*fao_param = buffer;
	memset ( buffer, 0, 8);
	if (f->code == UAI$_USERNAME) *fao_param = &username_d;
    }
}

main(int argc, char *argv[])
{
    field fields[] = {

    32, UAI$_USERNAME, "!AS,", "USERNAME", 	/* username                         */
    32, UAI$_ACCOUNT, "!AC,", "ACCOUNT", 	/* account name                     */
     2, UAI$_ASTLM, "!UW,", "ASTLM", 		/* AST queue limit                  */
     3, UAI$_BATCH_ACCESS_P, "!XL,", "BATCH_ACCESS_P", 	/* hourly batch access, primary     */
     3, UAI$_BATCH_ACCESS_S, "!XL,", "BATCH_ACCESS_S", 	/* hourly batch access, secondary   */
     2, UAI$_BIOLM, "!UW,", "BIOLM", 		/* buffered I/O limit               */
     4, UAI$_BYTLM, "!UL,", "BYTLM", 		/* buffered I/O byte count limit    */
    32, UAI$_CLITABLES, "!AC,", "CLITABLES", 	/* user CLI tables                  */
     4, UAI$_CPUTIM, "!UL,", "CPUTIM", 		/* CPU time quota                   */
    32, UAI$_DEFCLI, "!AC,", "DEFCLI", 		/* default command interpreter      */
    32, UAI$_DEFDEV, "!AC,", "DEFDEV", 		/* default device                   */
    64, UAI$_DEFDIR, "!AC,", "DEFDIR", 		/* default directory                */
     8, UAI$_DEF_PRIV, "!@XL,", "DEF_PRIV", 	/* default process privileges       */
     4, UAI$_DFWSCNT, "!UL,", "DFWSCNT", 	/* default working set size         */
     3, UAI$_DIALUP_ACCESS_P, "!UW,", "DIALUP_ACCESS_P", 	/* hourly dialup access, primary    */
     3, UAI$_DIALUP_ACCESS_S, "!UW,", "DIALUP_ACCESS_S", 	/* hourly dialup access, secondary  */
     2, UAI$_DIOLM, "!UW,", "DIOLM", 		/* direct I/O limit                 */
/*     4, UAI$_ENCRYPT, "!@XL,", "ENCRYPT", 	   encryption algorithm             */
/*     4, UAI$_ENCRYPT2, "!@XL,", "ENCRYPT2", 	   encryption algorithm for 2nd pwd */
     2, UAI$_ENQLM, "!UW,", "ENQLM", 		/* enqueue limit                    */
     8, UAI$_EXPIRATION, "!%D,", "EXPIRATION", 	/* expiration date for account      */
     2, UAI$_FILLM, "!UW,", "FILLM", 		/* open file limit                  */
     4, UAI$_FLAGS, "!XL,", "FLAGS", 		/* user flags longword              */
     2, UAI$_GRP, "!OW,", "GRP", 		/* group subfield                   */
     2, UAI$_JTQUOTA, "!UW,", "JTQUOTA", 	/* job-wide logical name table creation quota */
     8, UAI$_LASTLOGIN_I, "!%D,", "LASTLOGIN_I", /* date of last interactive login   */
     8, UAI$_LASTLOGIN_N, "!%D,", "LASTLOGIN_N", /* date of last non-interactive login */
     64, UAI$_LGICMD, "!AC,", "LGICMD", 		/* login command file               */
     3, UAI$_LOCAL_ACCESS_P, "!XW,", "LOCAL_ACCESS_P", 	/* hourly local access, primary     */
     3, UAI$_LOCAL_ACCESS_S, "!XW,", "LOCAL_ACCESS_S", 	/* hourly local access, secondary   */
     2, UAI$_LOGFAILS, "!UW,", "LOGFAILS", 	/* count of login failures          */
     2, UAI$_MAXACCTJOBS, "!UW,", "MAXACCTJOBS", /* maximum jobs for account allowed */
     2, UAI$_MAXDETACH, "!UW,", "MAXDETACH", 	/* maximum detached processes for UIC */
     2, UAI$_MAXJOBS, "!UW,", "MAXJOBS", 	/* maximum jobs for UIC allowed     */
/*   2, UAI$_MAX_CLASS, "!UW,", "MAX_CLASS", 	   maximum security class           */
     2, UAI$_MEM, "!OW,", "MEM", 		/* member subfield                  */
/*   2, UAI$_MIN_CLASS, "!UW,", "MIN_CLASS", 	   minimum security class           */
     3, UAI$_NETWORK_ACCESS_P,  "!XW,", "NETWORK_ACCESS_P", /* hourly network access, primary   */
     3, UAI$_NETWORK_ACCESS_S,  "!XW,", "NETWORK_ACCESS_S", /* hourly network access, secondary */
    32, UAI$_OWNER, "!AC,", "OWNER", 		/* owner's name                     */
/*   4, UAI$_PARENT_ID, "!XL,", "PARENT_ID", 	   identifier of owner of this account */
     4, UAI$_PBYTLM, "!UL,", "PBYTLM", 		/* paged buffer I/O byte count limit */
     4, UAI$_PGFLQUOTA, "!UL,", "PGFLQUOTA", 	/* page file quota                  */
     4, UAI$_PRCCNT, "!UL,", "PRCCNT", 		/* subprocess creation limit        */
     1, UAI$_PRI, "!UB,", "PRI", 		/* base process priority            */
     4, UAI$_PRIMEDAYS, "!XL,", "PRIMEDAYS", 	/* bits representing primary days   */
     8, UAI$_PRIV, "!@XL,", "PRIV", 		/* process privilege vector         */
/*     1, UAI$_PROXIES, "!UW,", "PROXIES", 	   number of proxies granted        */
/*     1, UAI$_PROXY_LIM, "!UW,", "PROXY_LIM", 	   number of proxies user can grant */
/*     1, UAI$_PWD, "!UW,", "PWD", 		   hashed password                  */
/*     1, UAI$_PWD2, "!UW,", "PWD2", 		   second password                  */
/*     1, UAI$_PWD2_DATE, "!UW,", "PWD2_DATE", 	   date of 2nd password change      */
     8, UAI$_PWD_DATE, "!%D,", "PWD_DATE", 	/* date of password change          */
     1, UAI$_PWD_LENGTH, "!UB,", "PWD_LENGTH", 	/* minimum password length          */
     8, UAI$_PWD_LIFETIME,  "!%D,", "PWD_LIFETIME", /* password lifetime                */
     1, UAI$_QUEPRI, "!UB,", "QUEPRI", 		/* maximum job queuing priority     */
     3, UAI$_REMOTE_ACCESS_P, "!XL,", "REMOTE_ACCESS_P", 	/* hourly remote access, primary    */
     3, UAI$_REMOTE_ACCESS_S, "!XL,", "REMOTE_ACCESS_S", 	/* hourly remote access, secondary  */
/*     1, UAI$_RTYPE, "!UW,", "RTYPE", 		   UAF record type                  */
/*     1, UAI$_SALT, "!UW,", "SALT", 		   random password salt             */
     2, UAI$_SHRFILLM, "!UW,", "SHRFILLM", 	/* shared file limit                */
/*     1, UAI$_SUB_ID, "!UW,", "SUB_ID", 	   user sub-identifier              */
     2, UAI$_TQCNT, "!UW,", "TQCNT", 		/* timer queue entry limit          */
     4, UAI$_UIC, "!XL,", "UIC", 		/* user ID code                     */
/*     1,  UAI$_USERNAME_TAG, "!UW,", "USERNAME_TAG", tag to differentiate records     */
/*     1, UAI$_USRDATOFF, "!UW,", "USRDATOFF", 	   offset of counted string of user data */
/*     1, UAI$_VERSION, "!UW,", "VERSION", 	   UAF format version               */
     4, UAI$_WSEXTENT, "!UL,", "WSEXTENT", 	/* working set size limit           */
     4, UAI$_WSQUOTA, "!UL,", "WSQUOTA"} ;	/* working set size quota           */

#define FIELDS sizeof ( fields ) / sizeof ( field )

    struct FAB	fab;
    struct RAB	rab;
    struct XABKEY	key;

    char    fao[512], out[1024], buffers[FIELDS][64], keybuf[32];
    int	    fao_params[FIELDS], i, j, k, l, s, context = -1, match;
    item    items[FIELDS + 1];

    $DESCRIPTOR (out_d, out);
    $DESCRIPTOR (fao_d, fao);

    fab = cc$rms_fab;
    rab = cc$rms_rab;
    key = cc$rms_xabkey;

    fab.fab$b_shr = FAB$M_SHRPUT;
    fab.fab$b_fac = FAB$M_GET;
    fab.fab$l_fna = "SYSUAF";
    fab.fab$b_fns = 6;
    fab.fab$l_dna = "SYS$SYSTEM:.DAT";
    fab.fab$b_dns = strlen (fab.fab$l_dna);
    fab.fab$l_xab = (void *) &key;

    rab.rab$l_fab = &fab;
    rab.rab$l_ubf = (char *) &out;
    rab.rab$w_usz = sizeof (out);
    rab.rab$l_kbf = keybuf;
    rab.rab$b_rac = RAB$C_KEY;

    out_p = out;
    fao_p = fao;
    k = 0;

    if (argc < 2) {
	printf ("Usage: getuai username [uai field list]\n");
	return 1;
	}

    k = 0;
    if (argc > 2) {
	for	(i = 2; i < argc; i++) {
	    match = 1;
	    for (j = 0; j < strlen(argv[i]); j++) argv[i][j]=_toupper(argv[i][j]);
	    for (j = 0; (j < FIELDS) && (match != 0); j++)
		match = strncmp(argv[i],fields[j].name,strlen(argv[i]));
	    j--;	    /* probably my programming bug. needed on VAXC. */
	    if (match == 0) {
		setup_field ( &fields[j], &items[k] , buffers[k], &fao_params[k] );
		k++;
	    } else printf ("NO match found for %s\n", argv[i]);
	}
    } else {
	for (; k < FIELDS; k++)
	    setup_field ( &fields[k], &items[k] , buffers[k], &fao_params[k] );
    }
    *(--out_p) = 0;
    printf ("%s\n", out);
    items[k].size =  0;
    items[k].code =  0;
    fao_d.dsc$w_length = fao_p - fao - 1; /* strip last comma */


    l = strlen(argv[1]);
    for (j = 0; j < l; j++) keybuf[j]=_toupper(argv[1][j]);
    rab.rab$b_ksz = l;

    s = SYS$OPEN ( &fab );
    if (!(s&1)) return s;
    s = SYS$CONNECT ( &rab );
    if (keybuf[0] == '*') {
	rab.rab$b_rac = RAB$C_SEQ;
	if (s & 1) s = SYS$FIND ( &rab );   /* skip password rec */
	}
    if (s & 1) s = SYS$FIND ( &rab );
    rab.rab$b_rac = RAB$C_SEQ;
    while (s & 1) {
	s = SYS$GET ( &rab );
	memcpy (username, &out[key.xab$w_pos0], 32);
	for (i = 0; !(isspace(username[i])); i++);
	username_d.dsc$w_length = i;
	if ( (keybuf[0] != '*') && 
	     strncmp(keybuf,username,strlen(keybuf)) != 0) break;
	out_d.dsc$w_length = sizeof ( out );
	if (s & 1) s = sys$getuai ( 0, &context, &username_d,  &items, 0, 0, 0);
	if (s & 1) s = sys$faol ( &fao_d, &out_d, &out_d, fao_params );
	if (s & 1) s = lib$put_output ( &out_d );
    }
    if (s==RMS$_EOF) s=1;
    return s ;
}
