/* ** LOGINOUT_CALLOUTS.C ** ** This program is a shared image that is activated by DEC's LOGINOUT.EXE. ** The program is linked as follows (/SHARE must be on the command line)... ** Alpha: ** $ LINK /SHARE=LOGINOUT_CALLOUTS.EXE /NOTRACE SYS$INPUT:/OPTION ** LOGINOUT_CALLOUTS.OBJ ** SYMBOL_VECTOR=(LGI$LOGINOUT_CALLOUTS=DATA) ** VAX: ** $ LINK /SHARE=LOGINOUT_CALLOUTS.EXE /NOTRACE SYS$INPUT:/OPTION ** LOGINOUT_CALLOUTS.OBJ ** UNIVERSAL=LGI$LOGINOUT_CALLOUTS ** ** The following steps are used to install and activate the program: ** $ COPY LOGINOUT_CALLOUTS.EXE SYS$COMMON:[SYSLIB] !(SYS$SHARE:) ** $ INSTALL ADD SYS$SHARE:LOGINOUT_CALLOUTS /OPEN /HEADER /SHARE ** $ DEFINE/SYSTEM/EXEC LGI$LOGINOUT_CALLOUTS LOGINOUT_CALLOUTS ** $ MCR SYSGEN ** SYSGEN> USE ACTIVE ** SYSGEN> SET LGI_CALLOUTS 1 ** SYSGEN> WRITE ACTIVE ** ** Repeat with "USE CURRENT" and "WRITE CURRENT" to make it permanent. ** Note file must have world read access, unless LOGINOUT has READALL. ** ** To replace an existing, active version of this program just COPY ** the new .EXE to SYS$COMMON:[SYSLIB] and then INSTALL REPLACE it. ** ** See the OpenVMS Utility Routines Manual for LOGINOUT callout documentation. */ /* ** INCLUDE FILES */ #include #include #include #include #include #include #include /* System service calls */ int SYS$ASSIGN(); int SYS$QIOW(); int SYS$DASSGN(); /* Define structure for the callout routines vector */ struct LGI$CALLOUT_VECTOR { long int LGI$L_ICR_ENTRY_COUNT; int (*LGI$ICR_INIT) (); int (*LGI$ICR_IACT_START) (); int (*LGI$ICR_DECWINIT) (); int (*LGI$ICR_IDENTIFY) (); int (*LGI$ICR_AUTHENTICATE) (); int (*LGI$ICR_CHKRESTRICT) (); int (*LGI$ICR_FINISH) (); int (*LGI$ICR_LOGOUT) (); int (*LGI$ICR_JOBSTEP) (); }; /* Define structure for the callout arguments vector */ struct LGI$ARG_VECTOR { void (*LGI$ICB_GET_INPUT) (); int (*LGI$ICB_DECW_IDENT) (); int (*LGI$ICB_DECW_AUTH) (); void (*LGI$ICB_GET_SYSPWD) (); int (*LGI$ICB_USERPROMPT) (); int (*LGI$ICB_USERPARSE) (); int (*LGI$ICB_AUTOLOGIN) (); int (*LGI$ICB_PASSWORD) (); int (*LGI$ICB_CHECK_PASS) (); int (*LGI$ICB_VALIDATE) (); void (*LGI$ICB_ACCTEXPIRED) (); void (*LGI$ICB_PWDEXPIRED) (); int (*LGI$ICB_DISUSER) (); void (*LGI$ICB_MODALHOURS) (); short *LGI$A_ICR_CREPRC_FLAGS; char *LGI$A_ICR_JOB_TYPE; char *LGI$A_ICR_SUBPROCESS; char *LGI$A_ICR_TERMINAL_DEV; struct dsc$descriptor_s *LGI$A_ICR_TT_PHYDEVNAM; struct dsc$descriptor_s *LGI$A_ICR_TT_ACCPORNAM; struct dsc$descriptor_s *LGI$A_ICR_CLINAME; struct dsc$descriptor_s *LGI$A_ICR_CLITABLES; struct dsc$descriptor_s *LGI$A_ICR_NCB; int *LGI$A_ICR_LOGLINK; struct dsc$descriptor_s *LGI$A_ICR_REM_NODE_NAM; struct dsc$descriptor_s *LGI$A_ICR_REM_ID; unsigned char *LGI$A_ICR_UAF_RECORD; struct RAB *LGI$A_ICR_INPUT_RAB; char *LGI$A_ICR_AUTOLOGIN; struct dsc$descriptor_s *LGI$A_ICR_USERNAME; struct dsc$descriptor_s *LGI$A_ICR_PWD1; struct dsc$descriptor_s *LGI$A_ICR_PWD2; int *LGI$A_ICR_PWDCOUNT; short int *LGI$A_ICR_NETFLAGS; }; /* Declare the callout routines that we define below. */ static int callout_iact_start(); static int callout_identify(); static int callout_authenticate(); /* ** Fill in the global array that tells LOGINOUT which of the callouts to make. ** The only callout routine filled in at initialization is LGI$ICR_IACT_START. ** The name LGI$LOGINOUT_CALLOUTS is required - it becomes a universal symbol. */ #pragma nostandard globaldef struct LGI$CALLOUT_VECTOR LGI$LOGINOUT_CALLOUTS = { 9, /* argument count */ NULL, /* general login init */ callout_iact_start, /* interactive start - initialized */ NULL, /* decwindows init */ NULL, /* identify - filled in if interactive */ NULL, /* authenticate - filled in if dialup */ NULL, /* check restrictions */ NULL, /* login finish */ NULL, /* logout */ NULL, /* each batch jobstep */ }; #pragma standard /*****************************************************************************/ /* ** Interactive initialization callout procedure. ** This callout is invoked on any interactive, non-DECwindows login. */ static int callout_iact_start(struct LGI$ARG_VECTOR *arg_vector) { int status; short iosb[4]; short iochan; char *question = "Are you a spy? "; char response[80]; /* Don't do any special processing if this is a subprocess. */ if (*arg_vector->LGI$A_ICR_SUBPROCESS) return (SS$_NORMAL); /* If process created with $CREPRC flag PRC$V_NOPASSWORD don't prompt. */ if (*arg_vector->LGI$A_ICR_CREPRC_FLAGS & PRC$M_NOPASSWORD) return (SS$_NORMAL); /* If we are here then we are an interactive terminal login. */ /* To change user name and password prompts uncomment below. */ /* LGI$LOGINOUT_CALLOUTS.LGI$ICR_IDENTIFY = callout_identify; */ /* LGI$LOGINOUT_CALLOUTS.LGI$ICR_AUTHENTICATE = callout_authenticate; */ /* Verify that a terminal is associated with this process. */ /* (In case $CREPRC used PRC$V_INTER bit and no terminal.) */ if (!*arg_vector->LGI$A_ICR_TERMINAL_DEV) return (SS$_NORMAL); /* Assign an I/O channel to the terminal device */ status = SYS$ASSIGN( arg_vector->LGI$A_ICR_TT_PHYDEVNAM, &iochan, NULL, NULL, NULL); if ( !(status&1) ) return (SS$_NORMAL); /* Check if the user is a bad guy */ status = SYS$QIOW( 0, iochan, IO$_READPROMPT|IO$M_PURGE|IO$M_TIMED|IO$M_CVTLOW , iosb, NULL, NULL, &response, sizeof(response), 30, NULL, question, strlen(question)); SYS$DASSGN( iochan); if (status&1) status = iosb[0]; if (status&1) { if (response[0]=='N' && response[1]=='O') return (SS$_NORMAL); status = LGI$_LOGDISABL; } return (status); }