Document revision date: 19 July 1999
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

OpenVMS Utility Routines Manual


Previous Contents Index

12.3.4 Callout Interface

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.

Table 12-3 Useful LOGINOUT Internal Variables
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:
  • Retrieves the job type with a GETJPI during initialization.
  • Modifies it during execution. (Its value may change between the LGI$ICR_INIT and later callouts.)
  • Writes it back into the JIB before exiting.

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:
  • NET_PROXY: A proxy request.
  • NET_PREAUTH: DECnet-Plus has preauthorized the login.
  • NET_DEFAULT_USER: The session or object database has a default user and no password checking is required.
  • NET_PROXY_OK: The requested proxy has been allowed by either LOGINOUT or the site-provided callout routines.

12.3.5 Sample Program

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); 
    } 

12.4 LOGINOUT Callout Routines

The following sections describe the individual callout routines. Each description includes the following:

The Typical Condition Values and the Associated OpenVMS Policy Function headings are unique to the LOGINOUT callout routines.


LGI$ICR_AUTHENTICATE

The LGI$ICR_AUTHENTICATE callout routine authenticates passwords.

Format

LGI$ICR_AUTHENTICATE arg_vector ,context


RETURNS


OpenVMS usage: cond_value
type: longword (unsigned)
access: write only
mechanism: by value

Returns status indicating whether and how to proceed with the login.


Arguments

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.

Description

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:

For all logins except DECwindows logins, the LGI$ICR_AUTHENTICATE callout routine may use the following callback routine sequence:

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.


Typical Condition Values

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.

Associated OpenVMS Policy Function

1
Perform standard password prompting and validation.

LGI$ICR_CHKRESTRICT

The LGI$ICR_CHKRESTRICT callout routine may be used to check site-specific access restrictions that are not usually included in the OpenVMS login.

Format

LGI$ICR_CHKRESTRICT arg_vector ,context


RETURNS


OpenVMS usage: cond_value
type: longword (unsigned)
access: write only
mechanism: by value

Returns status indicating whether and how to proceed with the login.


Arguments

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.

Description

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

Typical Condition Values

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.

Associated OpenVMS Policy Functions

1
Check password expiration, check DISUSER flag, check account expiration, and check restrictions on access time.


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
4493PRO_027.HTML