Document revision date: 19 July 1999 | |
Previous | Contents | Index |
Each image containing LOGINOUT callouts must define a universal symbol LGI$LOGINOUT_CALLOUTS. This symbol represents a vector of longwords that points to the entry points for the various callout routines, as shown in the following illustration:
The vector is headed by a longword count that delimits the number of callout routines supported by the callout module. Unused vector entries are identified by a 0 value.
Each callout routine has access to a vector of LOGINOUT internal variables, including the addresses of callback routines and other useful information. The vector entries are defined as offsets from the beginning of the vector. The vector has the following format:
Symbols of the form LGI$ICB_x are the addresses of the callback routines that the callout routines use to communicate with the user (see Table 12-2). Other offsets are addresses of useful variable information internal to LOGINOUT. These are described in Table 12-3.
Symbols | Definition |
---|---|
LGI$A_ICR_CREPRC_FLAGS | PPD_CREPRC_FLAGS controls program flow based on the major job types of PRC$V_BATCH, PRC$V_NETWRK, PRC$V_INTER, and other values such as PRC$V_NOPASSWORD (used for interactive jobs created on logged-in terminals). |
LGI$A_ICR_JOB_TYPE |
The job type from the JIB (byte). LOGINOUT does the following:
For interactive jobs, this flag indicates JIB$C_LOCAL, JIB$C_REMOTE, or JIB$C_DIALUP. |
LGI$A_ICR_SUBPROCESS | The subprocess flag (byte) indicates whether a subprocess is being logged in. |
LGI$A_ICR_TERMINAL_DEV | The terminal device flag (byte). |
LGI$A_ICR_TT_PHYDEVNAM | A descriptor containing the terminal's physical device name (null if input is not from a terminal). |
LGI$A_ICR_TT_ACCPORNAM | A descriptor containing the terminal's access port name (null if input is not from a terminal or is from a terminal without an associated access port). |
LGI$A_ICR_CLINAME | A descriptor containing the command language interpreter (CLI) name, parsed from the user name qualifiers. Valid only for interactive jobs. |
LGI$A_ICR_CLITABLES | A descriptor containing the CLI tables, parsed from the user name qualifiers. Valid only for interactive jobs. |
LGI$A_ICR_NCB | A descriptor containing the network control block. Valid only for network jobs. |
LGI$A_ICR_LOGLINK | A longword containing the local link number. Valid only for network jobs and when doing a SET HOST command from a DECnet-Plus remote terminal. |
LGI$A_ICR_REM_NODE_NAM | A descriptor containing the remote node name or a printable representation of its node number if the name is not available. Valid only for network jobs and when doing a SET HOST command from a DECnet-Plus remote terminal. |
LGI$A_ICR_REM_ID | A descriptor containing the remote ID. This may be the user ID on the remote system if the source operating system sends the user name. Otherwise, it is as defined for the source system. Valid only for network jobs and when doing a SET HOST command from a DECnet-Plus remote terminal. |
LGI$A_ICR_UAF_RECORD |
Address of the LOGINOUT internal variable containing the address of the
user authorization file (UAF) record.
Note that because the record will be written back to the UAF record, callout routines must not modify the contents of the UAF record. |
LGI$A_ICR_INPUT_RAB | A RAB (record access block) that may be used to communicate with an interactive user. |
LGI$A_ICR_AUTOLOGIN | A flag (byte) indicating whether an autologin is being used for this interactive job. |
LGI$A_ICR_USERNAME | A descriptor for handling the user name. |
LGI$A_ICR_PWD1 | A descriptor for handling the primary password. |
LGI$A_ICR_PWD2 | A descriptor for handling the secondary password. |
LGI$A_ICR_PWDCOUNT | A longword containing the count of passwords expected for this user. Valid only for interactive jobs. |
LGI$A_ICR_NETFLAGS |
A flag (word) containing authorization information. Valid only for
network jobs. The bits that have been defined are:
|
The following C program illustrates the use of LOGINOUT callouts. The sample program changes the user name and password prompts to "Who are you?" and "Prove it." The program also adds the message "Goodbye." at logout.
#module LGI$CALLOUT_EXAMPLE "TOY LOGINOUT callout example" /* **++ ** FACILITY: ** ** System help ** ** This program can be compiled with the following command ** ** $ CC/STANDARD=VAXC/LIST/PREFIX_LIBRARY_ENTRIES=ALL LGI$CALLOUT_EXAMPLE.C ** ** This program can be linked with the following example command procedure ** ** $ LINK/SHARE=LGI$CALLOUT_EXAMPLE SYS$INPUT/OPT ** LGI$CALLOUT_EXAMPLE.OBJ ** SYMBOL_VECTOR=(LGI$LOGINOUT_CALLOUTS=DATA) ** ** The following steps are used to install the program: ** ** $ DEFINE/SYSTEM/EXEC LGI$LOGINOUT_CALLOUTS LGI$CALLOUT_EXAMPLE ** ** If the program is not located in SYS$SHARE, define it as follows: ** ** $ DEFINE/SYSTEM/EXEC LGI$CALLOUT_EXAMPLE filespec ** ** [Remember that, without SYSNAM privilege, the /EXEC qualifier is ignored.] ** ** $ INSTALL ADD LGI$CALLOUT_EXAMPLE ** $ RUN SYS$SYSTEM:SYSGEN ** SYSGEN> USE ACTIVE ** SYSGEN> SET LGI_CALLOUTS 1 ** SYSGEN> WRITE ACTIVE ** ** The value of LGI_CALLOUTS is the number of separate callout images ** (of which this example is one) that are to be invoked. If there is ** more than one image, the logical LGI$LOGINOUT_CALLOUTS must have a ** list of equivalence names, one for each separate callout image. ** */ /* ** ** INCLUDE FILES ** */ #include descrip #include rms #include stsdef #include ssdef #include prcdef /* Declare structures for the callout vector and the callout arguments 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) (); }; struct LGI$ARG_VECTOR { int (*LGI$ICB_GET_INPUT) (); int (*reserved1) (); int (*reserved2) (); 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; }; globalvalue int LGI$_SKIPRELATED, /* callout's return status */ LGI$_DISUSER, LGI$_INVPWD, LGI$_NOSUCHUSER, LGI$_NOTVALID, LGI$_INVINPUT, LGI$_CMDINPUT, LGI$_FILEACC; static int callout_logout(); static int callout_decwinit(); static int callout_identify(); static int callout_authenticate(); globaldef struct LGI$CALLOUT_VECTOR LGI$LOGINOUT_CALLOUTS = { 9, 0, /* init */ 0, /* iact_start */ callout_decwinit, /* decwinit */ callout_identify, /* identify */ callout_authenticate, /* authenticate */ 0, /* chkrestrict */ 0, /* finish */ callout_logout, /* logout */ 0, /* jobstep */ }; /* DECwindows initialization */ static int callout_decwinit() { /* Disable any further calls */ LGI$LOGINOUT_CALLOUTS.LGI$L_ICR_ENTRY_COUNT = 0; /* Return and do standard DECwindows processing */ return (SS$_NORMAL); } /* Identification */ static int callout_identify(struct LGI$ARG_VECTOR *arg_vector) { int status; $DESCRIPTOR(wru,"\r\nWho are you? "); /* This example deals only with interactive jobs */ if (!(*arg_vector->LGI$A_ICR_CREPRC_FLAGS & PRC$M_INTER)) return(SS$_NORMAL); /* Not interactive, do normal processing */ if (*arg_vector->LGI$A_ICR_CREPRC_FLAGS & PRC$M_NOPASSWORD) return(SS$_NORMAL); /* Invoked as logged in, don't prompt */ if (*arg_vector->LGI$A_ICR_SUBPROCESS != 0) return(SS$_NORMAL); /* Don't prompt on subprocesses */ /* Check for autologin */ if ($VMS_STATUS_SUCCESS(arg_vector->LGI$ICB_AUTOLOGIN())) return (LGI$_SKIPRELATED); /* Yes, it's an autologin */ if (!$VMS_STATUS_SUCCESS(status = arg_vector->LGI$ICB_USERPROMPT(&wru))) return (status); /* On error, return error status */ /* Successful prompt and parse; skip OpenVMS policy */ return(LGI$_SKIPRELATED); } /* Authentication */ static int callout_authenticate(struct LGI$ARG_VECTOR *arg_vector) { int status; $DESCRIPTOR(proveit,"\r\nProve it: "); /* This example deals only with interactive jobs */ if (!(*arg_vector->LGI$A_ICR_CREPRC_FLAGS & PRC$M_INTER)) return(SS$_NORMAL); /* Not interactive, do normal processing */ if (*arg_vector->LGI$A_ICR_CREPRC_FLAGS & PRC$M_NOPASSWORD) return(SS$_NORMAL); /* Invoked as logged in, don't prompt */ if (*arg_vector->LGI$A_ICR_SUBPROCESS != 0) return(SS$_NORMAL); /* Don't prompt on subprocesses */ if (*arg_vector->LGI$A_ICR_PWDCOUNT != 0) /* This account has at least one password */ if (!$VMS_STATUS_SUCCESS(status = arg_vector->LGI$ICB_PASSWORD(0,&proveit))) return (status); /* On error, return error status */ if (*arg_vector->LGI$A_ICR_PWDCOUNT == 2) /* This account has two passwords */ if (!$VMS_STATUS_SUCCESS(status = arg_vector->LGI$ICB_PASSWORD(1,&proveit))) return (status); /* On error, return error status */ /* Successful prompt and password validation; skip OpenVMS policy */ return(LGI$_SKIPRELATED); } /* LOGOUT command */ static int callout_logout(username, procname, creprc_flags, write_fao) struct dsc$descriptor_s *username, *procname; short *creprc_flags; void (*write_fao) (); { char *Goodbye = " Goodbye."; /* This will become an ASCIC */ if ((int) write_fao != 0) /* If output is permitted... */ { Goodbye[0]=strlen(Goodbye)-1; /* Fill in ASCIC count */ write_fao(Goodbye); /* and write it */ } return(SS$_NORMAL); } |
The following sections describe the individual callout routines. Each description includes the following:
The LGI$ICR_AUTHENTICATE callout routine authenticates passwords.
LGI$ICR_AUTHENTICATE arg_vector ,context
OpenVMS usage: cond_value type: longword (unsigned) access: write only mechanism: by value
Returns status indicating whether and how to proceed with the login.
arg_vector
OpenVMS usage: vector type: vector_longword_unsigned access: modify mechanism: by reference
Vector containing callbacks and login information.context
OpenVMS usage: context type: longword (unsigned) access: modify mechanism: by reference
Pointer to site's local context.
All logins involving a password invoke the LGI$ICR_AUTHENTICATE callout routine. The routine is not called for subprocesses, network jobs invoked by proxy logins, or logged-in DECterm sessions.The following pointers are used in password authentication:
- Longword LGI$A_ICR_PWDCOUNT points to a location that contains the number of OpenVMS passwords for a particular account. Nonexistent accounts are assigned a password count of 1 to avoid revealing them by the absence of a password prompt.
- For DECwindows logins only, longword LGI$A_ICR_PWD1 points to a location that contains the user's primary password.
- For DECwindows logins only, longword LGI$A_ICR_PWD2 points to a location that contains the user's secondary password, if applicable.
For all logins except DECwindows logins, the LGI$ICR_AUTHENTICATE callout routine may use the following callback routine sequence:
- Call LGI$ICB_PASSWORD for standard password prompting with an optional nonstandard prompt and the option of checking or just returning the password or other information obtained.
- Call LGI$ICB_GET_INPUT for completely customized prompting for each required piece of authentication information.
For DECwindows logins, neither the LGI$ICB_PASSWORD callback routine nor the LGI$ICB_GET_INPUT callback routine needs to be called. The user enters the password using the DECwindows login dialog box before LOGINOUT issues the LGI$ICR_AUTHENTICATE callout.
For a complete description of the DECwindows flow of control, see the description of the LGI$ICR_DECWINIT callout routine.
All logins involving a password may invoke the LGI$ICB_VALIDATE callback routine. This routine validates against SYSUAF.DAT passwords obtained by customized prompting using descriptors for the user name and passwords. Optionally, the login may call the LGI$_ICB_CHECK_PASS callback routine to validate passwords. For interactive jobs, the LGI$ICR_AUTHENTICATE routine should check the DISUSER flag using the LGI$ICB_DISUSER callback routine to preserve the consistency of the invalid user behavior for disabled accounts. For other types of jobs, use the LGI$ICR_CHKRESTRICT callout routine to check the DISUSER flag.
Note
LOGINOUT checks the DISUSER flag as part of the authentication process because, if it is checked later, an intruder could determine that the correct user name and password had been entered and that the account is disabled. This is deliberately hidden by keeping the user in the retry loop for a disabled account.If the DISUSER flag is checked with other access restrictions in the authorization portion, this causes an immediate exit from LOGINOUT.
Break-in detection, intrusion evasion, and security auditing are done in the case of any failure return from LGI$ICR_AUTHENTICATE.
If this routine returns LGI$_SKIPRELATED, the user is fully authenticated, and no further authentication is done by either the site or OpenVMS. If this routine returns an error for an interactive job, the system retries the identification and authentication portions of LOGINOUT. For character-cell terminals, this consists of calling the LGI$ICR_IDENTIFY and LGI$ICR_AUTHENTICATE callout routines; for DECwindows terminals, this consists of calling the LGI$ICR_DECWINIT routine. The number of retries is specified by the SYSGEN parameter LGI_RETRY_LIM.
SS$_NORMAL Access permitted; continue policy checks. LGI$_SKIPRELATED Access permitted; omit calls to the LGI$ICR_AUTHENTICATE callout routine in subsequent images and calls to the associated OpenVMS policy function. Other Disallow the login; perform break-in detection, intrusion evasion, and security auditing. For interactive logins, retry identification and authentication portions of LOGINOUT, up to the number specified in the SYSGEN parameter LGI_RETRY_LIM.
Perform standard password prompting and validation.
The LGI$ICR_CHKRESTRICT callout routine may be used to check site-specific access restrictions that are not usually included in the OpenVMS login.
LGI$ICR_CHKRESTRICT arg_vector ,context
OpenVMS usage: cond_value type: longword (unsigned) access: write only mechanism: by value
Returns status indicating whether and how to proceed with the login.
arg_vector
OpenVMS usage: vector type: vector_longword_unsigned access: modify mechanism: by reference
Vector containing callbacks and login information.context
OpenVMS usage: context type: longword (unsigned) access: modify mechanism: by reference
Pointer to site's local context.
All logins call this routine after the password is authenticated to allow the site to check other access restrictions. The site may check its own access restrictions and any of the following OpenVMS access restrictions:
Access Restriction Callback Routine Used to Check Restriction Account expiration LGI$ICB_ACCTEXPIRED Password expiration LGI$ICB_PWDEXPIRED Account disabled LGI$ICB_DISUSER Access modes and times LGI$ICB_MODALHOURS
SS$_NORMAL Access permitted; continue policy checks, including all of the normal OpenVMS policy functions associated with the callback routines used to check restrictions. LGI$_SKIPRELATED Access permitted; omit calls to the LGI$ICR_CHKRESTRICT callout routine in subsequent images and calls to the associated OpenVMS policy functions. Other Disallow the login.
Check password expiration, check DISUSER flag, check account expiration, and check restrictions on access time.
Previous | Next | Contents | Index |
privacy and legal statement | ||
4493PRO_027.HTML |