#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef unsigned int QUAD[2]; /* VAX quadword */ typedef unsigned int LONG; /* vax longword */ typedef unsigned int ADDRESS; /* address quantity */ typedef unsigned short int WORD; /* 16 bit word */ typedef unsigned char BYTE; /* 8 bits */ typedef unsigned char LOGICAL; /* cheapest */ #define str2desc( desc , string ) \ { desc.dsc$w_length = strlen(string); \ desc.dsc$a_pointer = string; \ desc.dsc$b_class = DSC$K_CLASS_S; \ desc.dsc$b_dtype = DSC$K_DTYPE_T; \ } typedef struct _item { short length; /* length of data buffer */ short code; /* item code */ BYTE *buffer; /* data buffer */ int *retlen; /* returned item length */ } ITEM; /* verify_user * Verify this username/password combination against the UAF. * Inputs: username, password. * Returns VMS system call status - should always be SS$_NORMAL unless * some unexpected strange system service status. * * Returns one of the following in user_status: */ unsigned long int verf_user ( char *username, char *password ) { LONG status, uai_flags, day_of_week,hour_of_day,operation,prim_days; QUAD uai_pwd_date, uai_pwd_lifetime, uai_pwd, putative_pw, uai_pwd_expiration, now, warn_if_before,sys_time; WORD uai_salt; BYTE uai_encrypt; LONG uai_dial_p,uai_dial_s; struct dsc$descriptor dsc$usr, dsc$pwd; /* $GETUAI this user. Return the following fields: * UAI$_FLAGS (we are interested in UAI$V_DISACNT, UAI$V_PWD_EXPIRED) * UAI$_PWD_DATE (date of last pw change) * UAI$_PWD_LIFETIME * UAI$_ENCRYPT (encryption algorithm used) * UAI$_SALT * UAI$_PWD */ ITEM itmlst[] = { {4, UAI$_FLAGS, &uai_flags, 0}, {8, UAI$_PWD_DATE, uai_pwd_date, 0}, {8, UAI$_PWD_LIFETIME, uai_pwd_lifetime,0}, {1, UAI$_ENCRYPT, &uai_encrypt, 0}, {2, UAI$_SALT, &uai_salt, 0}, {8, UAI$_PWD, uai_pwd, 0}, {3, UAI$_DIALUP_ACCESS_P, &uai_dial_p, 0}, {3, UAI$_DIALUP_ACCESS_S, &uai_dial_s, 0}, {4, UAI$_PRIMEDAYS, &prim_days, 0}, {0, 0, 0, 0} }; str2desc(dsc$usr, username); status = str$upcase(&dsc$usr,&dsc$usr); if (!$VMS_STATUS_SUCCESS(status)) lib$signal(status); status = SYS$GETUAI(0, 0, &dsc$usr, &itmlst, 0, 0, 0); if (status == RMS$_RNF || (UAI$M_DISACNT & uai_flags)) { /* * A record was not found for this username, or the guy's disuser'd */ return status; } if ( !(status & 1) ) lib$signal(status); /* Now hash the putative password to see if it matches the one on file. */ str2desc(dsc$pwd, password); status = str$upcase(&dsc$pwd,&dsc$pwd); if (!$VMS_STATUS_SUCCESS(status)) lib$signal(status); status = SYS$HASH_PASSWORD(&dsc$pwd, uai_encrypt, uai_salt, &dsc$usr, putative_pw); if ( !(status & 1) ) return(status); if ((putative_pw[0] != uai_pwd[0]) || putative_pw[1] != uai_pwd[1]) { return -1; } /* The putative password matches the one on file, but has it expired? */ /* if (UAI$M_PWD_EXPIRED & uai_flags) { return -1; } */ /* * Getting and convert internal system time */ operation = LIB$K_DAY_OF_WEEK; status = lib$cvt_from_internal_time(&operation,&day_of_week); if ( !(status & 1) ) lib$signal(status); operation = LIB$K_HOUR_OF_DAY; status = lib$cvt_from_internal_time(&operation,&hour_of_day); if ( !(status & 1) ) lib$signal(status); /* * Check allowed access time for this account */ hour_of_day = 1 <