From:	MERC::"uunet!CRVAX.SRI.COM!RELAY-INFO-VAX" 26-JUN-1992 11:53:01.68
To:	info-vax@kl.sri.com
CC:	
Subj:	Re: SYSUAF format

Ken Connelly writes:

>>>Is the format of SYS$SYSTEM:SYSUAF.DAT documented anywhere in the grey
>>>wall?  If so, where?  If not, is the fiche the only place to look?  'Cause
>>>I don't have that available.

...and in another article:

>
>In other words, I don't want to feed a program every username read out of
>SYSUAF.LIS (or somewhere similar) just to see if the criteria I'm
>interested in is a match.  I just want to read a record, save something
>from it if it meets some criteria, then read the next record.
>
>I *know* DEC doesn't support reading SYSUAF that way.  I'm willing to take
>my lumps when they change the format.

>===========================================================================
>Ken Connelly, Systems/Operations Manager         Internet: connelly@uni.edu
>Information Systems and Computing Services
>University of Northern Iowa                       USWestNet: (319) 273-2357
>Cedar Falls, IA  50614-0121                             FAX: (319) 273-3509
>As time goes on, it becomes more and more apparent that elected officials 
>should be required to pass a competency test.  Then we wouldn't have any, 
>and all would be right with the world!
>===========================================================================

Well, talk about being in the right place at the right time, I spent
yesterday afternoon doing this very thing.  My resulting code is attached
below.  Included are two files, uaf.c, which opens the sysuaf.dat and loops
through the records, and uafdef.h, which contains a definition for the
uaf records.  uafdef.h I created by executing the following line:

$ library/extract=$uafdef/output=uafdef.h sys$library:lib.mlb.

I then edited the result to make a C struct.  (Lots of EVE macros,
I wasn't going to do this by hand :^) )  The tricky parts were (a)
places where the same chunk of memory has 2 names, a la UIC definitions;
and (b) finding out where the filler goes.  I tell you this not to
impress you, but to give you some pointers in case your UAF structure
is not the same as the one I got from my library.

The documentation in the System Services manual for $GETUAI should
document what the fields are.

BIG DISCLAIMER:  I wrote this only yesterday, and tested it on only
a couple of fields in my small (25 user) UAF file, under VMS 5.4 on
a microvaxIII.  It worked there, but no guarantees for you.

If you make any structural changes, or find any bugs, please email
me at davis@interlan.interlan.com or davis@wilma.interlan.com.

Hope this helps,

-mad

================== cut here for uaf.c ===============================

#include	stdio
#include	"uafdef.h"
#include	ssdef
#include	rmsdef
#include	fab
#include	rab
#include	time

main( int argc, char ** argv )
	{
	struct uaf_rec	uaf;
	struct FAB	fab_uaf;
	struct RAB	rab_uaf;
	int	status;
	char	* uafname = "SYS$SYSROOT:[SYSEXE]SYSUAF.DAT;0";
	int	i = 0;
	time_t	login_time;

	/* init the fab */

	fab_uaf = cc$rms_fab;
	fab_uaf.fab$b_org = FAB$C_IDX;	/* indexed file */
	fab_uaf.fab$b_rfm = FAB$C_VAR;	/* variable length records */
	fab_uaf.fab$b_shr = FAB$M_GET | FAB$M_PUT | FAB$M_DEL |
				FAB$M_UPD | FAB$M_UPI ;
	fab_uaf.fab$l_fna = uafname;
	fab_uaf.fab$b_fns = strlen( uafname );

	/* init the rab */

	rab_uaf = cc$rms_rab;
	rab_uaf.rab$l_fab = &fab_uaf;
	rab_uaf.rab$b_rac = RAB$C_SEQ;	/* to read all records */
					/* keyed alphabetically by User */
	rab_uaf.rab$w_usz = UAF$K_LENGTH;
	rab_uaf.rab$l_ubf = &uaf;

	/* open the file */

	status = SYS$OPEN( &fab_uaf );
	if ( status != SS$_NORMAL && status != RMS$_NORMAL )
		{
		printf( "open: " );
		exit( status );
		}

	/* connect the record stream */

	status = SYS$CONNECT( &rab_uaf );
	if ( status != SS$_NORMAL && status != RMS$_NORMAL )
		{
		printf( "connect: " );
		exit( status );
		}

	/* read records */

	for ( ;; )
		{
		status = SYS$GET( &rab_uaf );
		if ( status != SS$_NORMAL && status != RMS$_NORMAL )
			break;
		i++;
		uaf.uaf_t_username[ 31 ] = '\0';
		login_time = shell$fix_time( uaf.uaf_q_lastlogin_i );
		if ( (long)login_time < 0 )
			continue;
		printf( "%32.32s %s", uaf.uaf_t_username,
				ctime( &login_time ));
		}
	printf( "\n %d records read", i );


	/* close up */

	SYS$DISCONNECT( &rab_uaf );
	SYS$CLOSE( &fab_uaf );
	exit( status );
	}

================== end of uaf.c =====================================

================== cut here for uafdef.h ============================

#define	UAF$C_USER_ID	1
#define	UAF$C_VERSION1	1
#define	UAF$C_KEYED_PART	52
#define	UAF$C_MAX_PWD_LENGTH	32
#define	UAF$K_MAX_PWD_LENGTH	32
#define	UAF$C_AD_II	0
#define	UAF$C_PURDY	1
#define	UAF$C_PURDY_V	2
#define	UAF$C_PURDY_S	3
#define	UAF$C_PREFERED_ALGORITHM	3
#define	UAF$K_PREFERED_ALGORITHM	3
#define	UAF$C_CUST_ALGORITHM	128
#define	UAF$K_CUST_ALGORITHM	128
#define	UAF$K_FIXED	644
#define	UAF$C_FIXED	644
#define	UAF$K_LENGTH	1412
#define	UAF$C_LENGTH	1412
#define	UAF$S_UAFDEF	1412

#define	UAF$B_RTYPE	0
#define	UAF$B_VERSION	1
#define	UAF$W_USRDATOFF	2
#define	UAF$S_USERNAME	32
#define	UAF$T_USERNAME	4
#define	UAF$T_USERNAME_TAG	35
#define	UAF$L_UIC	36
#define	UAF$W_MEM	36
#define	UAF$W_GRP	38
#define	UAF$L_SUB_ID	40
#define	UAF$S_PARENT_ID	8
#define	UAF$Q_PARENT_ID	44
#define	UAF$S_ACCOUNT	32
#define	UAF$T_ACCOUNT	52
#define	UAF$S_OWNER	32
#define	UAF$T_OWNER	84
#define	UAF$S_DEFDEV	32
#define	UAF$T_DEFDEV	116
#define	UAF$S_DEFDIR	64
#define	UAF$T_DEFDIR	148
#define	UAF$S_LGICMD	64
#define	UAF$T_LGICMD	212
#define	UAF$S_DEFCLI	32
#define	UAF$T_DEFCLI	276
#define	UAF$S_CLITABLES	32
#define	UAF$T_CLITABLES	308
#define	UAF$S_PWD	8
#define	UAF$Q_PWD	340
#define	UAF$L_PWD	340
#define	UAF$S_PWD2	8
#define	UAF$Q_PWD2	348
#define	UAF$W_LOGFAILS	356
#define	UAF$W_SALT	358
#define	UAF$B_ENCRYPT	360
#define	UAF$B_ENCRYPT2	361
#define	UAF$B_PWD_LENGTH	362
#define	UAF$S_EXPIRATION	8
#define	UAF$Q_EXPIRATION	364
#define	UAF$S_PWD_LIFETIME	8
#define	UAF$Q_PWD_LIFETIME	372
#define	UAF$S_PWD_DATE	8
#define	UAF$Q_PWD_DATE	380
#define	UAF$S_PWD2_DATE	8
#define	UAF$Q_PWD2_DATE	388
#define	UAF$S_LASTLOGIN_I	8
#define	UAF$Q_LASTLOGIN_I	396
#define	UAF$S_LASTLOGIN_N	8
#define	UAF$Q_LASTLOGIN_N	404
#define	UAF$S_PRIV	8
#define	UAF$Q_PRIV	412
#define	UAF$S_DEF_PRIV	8
#define	UAF$Q_DEF_PRIV	420
#define	UAF$S_MIN_CLASS	20
#define	UAF$R_MIN_CLASS	428
#define	UAF$S_MAX_CLASS	20
#define	UAF$R_MAX_CLASS	448
#define	UAF$L_FLAGS	468
#define	UAF$V_DISCTLY	0
#define	UAF$V_DEFCLI	1
#define	UAF$V_LOCKPWD	2
#define	UAF$V_RESTRICTED	3
#define	UAF$V_DISACNT	4
#define	UAF$V_DISWELCOM	5
#define	UAF$V_DISMAIL	6
#define	UAF$V_NOMAIL	7
#define	UAF$V_GENPWD	8
#define	UAF$V_PWD_EXPIRED	9
#define	UAF$V_PWD2_EXPIRED	10
#define	UAF$V_AUDIT	11
#define	UAF$V_DISREPORT	12
#define	UAF$V_DISRECONNECT	13
#define	UAF$V_AUTOLOGIN	14
#define	UAF$V_DISFORCE_PWD_CHANGE	15
#define	UAF$V_CAPTIVE	16
#define	UAF$V_DISIMAGE	17
#define	UAF$V_DISPWDDIC	18
#define	UAF$V_DISPWDHIS	19
#define	UAF$S_NETWORK_ACCESS_P	3
#define	UAF$B_NETWORK_ACCESS_P	472
#define	UAF$S_NETWORK_ACCESS_S	3
#define	UAF$B_NETWORK_ACCESS_S	475
#define	UAF$S_BATCH_ACCESS_P	3
#define	UAF$B_BATCH_ACCESS_P	478
#define	UAF$S_BATCH_ACCESS_S	3
#define	UAF$B_BATCH_ACCESS_S	481
#define	UAF$S_LOCAL_ACCESS_P	3
#define	UAF$B_LOCAL_ACCESS_P	484
#define	UAF$S_LOCAL_ACCESS_S	3
#define	UAF$B_LOCAL_ACCESS_S	487
#define	UAF$S_DIALUP_ACCESS_P	3
#define	UAF$B_DIALUP_ACCESS_P	490
#define	UAF$S_DIALUP_ACCESS_S	3
#define	UAF$B_DIALUP_ACCESS_S	493
#define	UAF$S_REMOTE_ACCESS_P	3
#define	UAF$B_REMOTE_ACCESS_P	496
#define	UAF$S_REMOTE_ACCESS_S	3
#define	UAF$B_REMOTE_ACCESS_S	499
#define	UAF$B_PRIMEDAYS	514
#define	UAF$V_MONDAY	0
#define	UAF$V_TUESDAY	1
#define	UAF$V_WEDNESDAY	2
#define	UAF$V_THURSDAY	3
#define	UAF$V_FRIDAY	4
#define	UAF$V_SATURDAY	5
#define	UAF$V_SUNDAY	6
#define	UAF$B_PRI	516
#define	UAF$B_QUEPRI	517
#define	UAF$W_MAXJOBS	518
#define	UAF$W_MAXACCTJOBS	520
#define	UAF$W_MAXDETACH	522
#define	UAF$W_PRCCNT	524
#define	UAF$W_BIOLM	526
#define	UAF$W_DIOLM	528
#define	UAF$W_TQCNT	530
#define	UAF$W_ASTLM	532
#define	UAF$W_ENQLM	534
#define	UAF$W_FILLM	536
#define	UAF$W_SHRFILLM	538
#define	UAF$L_WSQUOTA	540
#define	UAF$L_DFWSCNT	544
#define	UAF$L_WSEXTENT	548
#define	UAF$L_PGFLQUOTA	552
#define	UAF$L_CPUTIM	556
#define	UAF$L_BYTLM	560
#define	UAF$L_PBYTLM	564
#define	UAF$L_JTQUOTA	568
#define	UAF$W_PROXY_LIM	572
#define	UAF$W_PROXIES	574
#define	UAF$W_ACCOUNT_LIM	576
#define	UAF$W_ACCOUNTS	578

struct uaf_rec
	{
	unsigned char	uaf_b_rtype;
	unsigned char	uaf_b_version;
	short		uaf_w_usrdatoff;
	unsigned char	uaf_t_username[	32 ];
	variant_union
		{
		long		uaf_l_uic;
		variant_struct
			{
			short		uaf_w_mem;
			short		uaf_w_grp;
			} uic_w;
		} uic;
	long		uaf_l_sub_id;
	unsigned long	uaf_q_parent_id[ 2 ];
	unsigned char	uaf_t_account[ 32 ];
	unsigned char	uaf_t_owner[ 32 ];
	unsigned char	uaf_t_defdev[ 32 ];
	unsigned char	uaf_t_defdir[ 64 ];
	unsigned char	uaf_t_lgicmd[ 64 ];
	unsigned char	uaf_t_defcli[ 32 ];
	unsigned char	uaf_t_clitables[ 32 ];
	variant_union
		{
		unsigned long	uaf_q_pwd[ 2 ];
		long		uaf_l_pwd;
		} pwd;
	unsigned long	uaf_q_pwd2[ 2 ];
	short		uaf_w_logfails;
	short		uaf_w_salt;
	unsigned char	uaf_b_encrypt;
	unsigned char	uaf_b_encrypt2;
	unsigned char	uaf_b_pwd_length;
	unsigned char	uaf_b_filler_1;
	unsigned long	uaf_q_expiration[ 2 ];
	unsigned long	uaf_q_pwd_lifetime[ 2 ];
	unsigned long	uaf_q_pwd_date[ 2 ];
	unsigned long	uaf_q_pwd2_date[ 2 ];
	unsigned long	uaf_q_lastlogin_i[ 2 ];
	unsigned long	uaf_q_lastlogin_n[ 2 ];
	unsigned long	uaf_q_priv[ 2 ];
	unsigned long	uaf_q_def_priv[ 2 ];
	unsigned char	uaf_r_min_class[ 20 ];
	unsigned char	uaf_r_max_class[ 20 ];
	long		uaf_l_flags;
/*	uaf_v_disctly	0	*/
/*	uaf_v_defcli	1	*/
/*	uaf_v_lockpwd	2	*/
/*	uaf_v_restricted	3	*/
/*	uaf_v_disacnt	4	*/
/*	uaf_v_diswelcom	5	*/
/*	uaf_v_dismail	6	*/
/*	uaf_v_nomail	7	*/
/*	uaf_v_genpwd	8	*/
/*	uaf_v_pwd_expired	9	*/
/*	uaf_v_pwd2_expired	10	*/
/*	uaf_v_audit	11	*/
/*	uaf_v_disreport	12	*/
/*	uaf_v_disreconnect	13	*/
/*	uaf_v_autologin	14	*/
/*	uaf_v_disforce_pwd_change	15	*/
/*	uaf_v_captive	16	*/
/*	uaf_v_disimage	17	*/
/*	uaf_v_dispwddic	18	*/
/*	uaf_v_dispwdhis	19	*/
	unsigned char	uaf_b_network_access_p[ 3 ];
	unsigned char	uaf_b_network_access_s[ 3 ];
	unsigned char	uaf_b_batch_access_p[ 3 ];
	unsigned char	uaf_b_batch_access_s[ 3 ];
	unsigned char	uaf_b_local_access_p[ 3 ];
	unsigned char	uaf_b_local_access_s[ 3 ];
	unsigned char	uaf_b_dialup_access_p[ 3 ];
	unsigned char	uaf_b_dialup_access_s[ 3 ];
	unsigned char	uaf_b_remote_access_p[ 3 ];
	unsigned char	uaf_b_remote_access_s[ 3 ];
	unsigned char	uaf_b_filler_2[ 12 ];
	unsigned char	uaf_b_primedays;
	unsigned char	uaf_b_filler_3;
/*	uaf_v_monday	0	*/
/*	uaf_v_tuesday	1	*/
/*	uaf_v_wednesday	2	*/
/*	uaf_v_thursday	3	*/
/*	uaf_v_friday	4	*/
/*	uaf_v_saturday	5	*/
/*	uaf_v_sunday	6	*/
	unsigned char	uaf_b_pri;
	unsigned char	uaf_b_quepri;
	short		uaf_w_maxjobs;
	short		uaf_w_maxacctjobs;
	short		uaf_w_maxdetach;
	short		uaf_w_prccnt;
	short		uaf_w_biolm;
	short		uaf_w_diolm;
	short		uaf_w_tqcnt;
	short		uaf_w_astlm;
	short		uaf_w_enqlm;
	short		uaf_w_fillm;
	short		uaf_w_shrfillm;
	long		uaf_l_wsquota;
	long		uaf_l_dfwscnt;
	long		uaf_l_wsextent;
	long		uaf_l_pgflquota;
	long		uaf_l_cputim;
	long		uaf_l_bytlm;
	long		uaf_l_pbytlm;
	long		uaf_l_jtquota;
	short		uaf_w_proxy_lim;
	short		uaf_w_proxies;
	short		uaf_w_account_lim;
	short		uaf_w_accounts;
	unsigned char	uaf_b_filler[ UAF$K_LENGTH - UAF$W_ACCOUNTS - sizeof( short )];
	};

================== end of uafdef.h ==================================


-mad 

---------------------------------------------------------------------------
| Michael A. Davis                davis@interlan.interlan.com             |
| Network & Communications Management, Inc.                               |
|                              =*=                                        |
| mad: (adj.) affected by a certain degree of intellectual independence   |
|                  - Ambrose Bierce                                       |
---------------------------------------------------------------------------

-- 

-mad 

---------------------------------------------------------------------------

