HP OpenVMS Systems Documentation

Content starts here

OpenVMS Programming Concepts Manual


Previous Contents Index

33.3.8 Synchronization of Your System Service Calls

As with many other system services, you have your choice of the SYS$ACM or SYS$ACMW interface. Choose one or the other based on whether your program will be doing other work (authentication-related or otherwise) while the authentication operation is underway. This choice has only to do with synchronization within your program; it is unrelated to your choice of dialogue mode or nondialogue mode.

33.4 Authentication Techniques

Your ACM client program can call the SYS$ACM[W] system service to change a password, and the effect is the same as if SET PASSWORD had made the call.

Your ACM client program can call the SYS$ACM[W] system service to authenticate a user. Your authentication is audited and break-in evasion is checked in the ACME server process, just as for LOGINOUT.

Your program can call the SYS$ACM[W] system service to log an event or to query for information specific to a particular domain of interpretation (DOI). With the exception of the general ACM information described in Section 33.4.5.3, Looking Up DOI and ACME IDs, all use of the Event or Query function codes is specific to a DOI.

33.4.1 Nondialogue Mode Operation

The simplest form of call to the SYS$ACM[W] system service is the nondialogue mode call, illustrated in Figure 33-4. It resembles many other system services, except that the item list contains a wider variety of both input and output items.

Figure 33-4 Nondialogue Mode Operation


Use nondialogue mode when only a limited amout of interaction is possible, such as when an existing network protocol like FAL or FTP does not allow an arbitrary authentication exchange. Typically, such programs should specify an ACME$_LOGON_TYPE of ACME$K_NETWORK, indicating that while they supply a password, no complex interaction is possible.

33.4.2 Dialogue Mode Operation

Use dialogue mode when your ACM client program is flexible enough to respond to password change notification, to allow the user to answer arbitrary questions, such as the charge code for a session, and so on.

In dialogue mode, the SYS$ACM[W] system service uses the longword you provide by the ACM context argument parameter to store a pointer to an ACM communications buffer. Figure 33-5 illustrates dialogue mode operation.

Figure 33-5 Dialogue Mode


As with nondialogue mode, your ACM client program must provide on the initial call to the SYS$ACM[W] system service all output items and all input items that are not going to be the subject of an itemset entry.

On intermediate returns, where the SYS$ACM[W] system service provides the primary status ACME$_OPINCOMPL in ACMESB$L_STATUS, it also creates an itemset within the ACM communications buffer indicating what further information exchange is required. The action your program should take depends upon the nature of each itemset entry within the itemset as follows:

  • Output itemset entries
    The SYS$ACM[W] system service provides information for display to the user. The exact form of this display is up to your program, as guided by the message category provided in field ACMEIS$W_MSG_TYPE and by the item code provided in field ACMEIS$W_ITEM_CODE. Your program may in fact choose to ignore any or all output itemset entries, except for certain message category values that would not be appropriate, such as suppressing ACMEMC$K_SELECTION information that tells users about possible choices for their next input.
  • Input itemset entries
    The SYS$ACM[W] system service provides information regarding input needed on the next call to the SYS$ACM[W] system service. In the simplest case, you can handle this by prompting a character cell terminal, using the prompt text provided in the itemset entry. For a more complex interface, some of the information sought might be provided by the program without user interaction, for instance if authentication were being done with the assistance of a smart card or other personalized hardware device.

If all of the itemset entries within the itemset were output itemset entries, your program should call the SYS$ACM[W] system service with an empty item list (containing just the terminator entry).

Dialogue mode operation applies only to the Authenticate Principal and Change Password functions. Calls to any other functions must be in nondialogue mode.

33.4.3 Login Categories and Classes

The OpenVMS Guide to System Security outlines the following login categories and login classes that are of interest for calling the SYS$ACM[W] system service:

Login Category Login Class
Interactive Local, Dialup, Remote
Noninteractive Batch, Network

Those login classes correspond to the values used in the ACME$_LOGON_TYPE item for the SYS$ACM[W] system service. Each may have specific policy requirements, and may be authenticated differently. Batch jobs, for example, start without specification of a password or other authentication information.

This choice can also influence authorization decisions, such as the VMS day and time restrictions.

Specifying item ACME$_LOGON_TYPE requires the IMPERSONATE privilege. It is defaulted to match the login class of the process that called the SYS$ACM[W] system service.

The login type affects the degree of interaction required to call the SYS$ACM[W] system service, as shown in the following table:

Login Type Interaction Details
Batch No authentication is involved. This may mean that credentials are not provided for certain domains of interpretation that base their credential creation on presentation of a password.
Network Authentication is involved, but it operates in nondialogue mode unless an ACME agent (other than the VMS ACME agent) requires dialogue for authentication.
Local, Dialup, and Remote Authentication is involved and further dialogue may be encountered to change expiring passwords, and so on. The SYS$ACM[W] system service expects a person to be available to answer questions raised through dialogue.

Thus in the case of the local, dialup, or remote values for ACME$_LOGON_TYPE, you must provide an ACM context argument argument on all calls to the SYS$ACM[W] system service (and you must provide item ACME$_DIALOGUE_SUPPORT on the initial call to indicate support for input dialogue). With the network value for ACME$_LOGON_TYPE, those elements might be required with certain add-on ACME agents.

33.4.4 Principal Names

So long as there is no targeting by the caller of the SYS$ACM[W] system service (discussed in Section 33.4.5), the decision regarding which ACME agent handles a particular request is governed by the following factors:

  • The ordering of ACME agents selected by the system manager
  • The syntax of the principal name
  • The spelling of the principal name

If the syntax provided to the SYS$ACM[W] system service can be handled by only one ACME agent, that settles the matter. If it can be handled by more than one ACME agent, then the decision also depends on which ACME agent (in order) is the first to be able to map the particular principal name to a VMS user name.

Whether a particular ACME agent can map a particular principal name also depends on the mapping tables or algorithms specific to that ACME agent, but this is typically more time-consuming than simple decisions made on the basis of the syntax presented in the principal name. Consider the acceptable syntax presented in the following table:

Domain of Interpretation Principal Name Syntax
VMS username
Windows NT domain\user OR user@domain OR user

Given those two ACME agents, it is possible to specify a principal name that can only be handled by the Windows NT DOI (by a full specification including the execute (@) command), but it is not possible to specify a principal name that can only be handled by the VMS DOI.

But that table only describes the situation for the combination of those two ACME agents, the initial ones produced by Compaq. The VMS ACME is always present on any OpenVMS system, but on some systems you might omit the NT ACME and/or include some other ACME agents, one of which might honor some of the same syntax as the NT ACME agent.

33.4.5 Targeting Your System Service Calls

Most Authenticate Principal and Change Password calls are handled by one or more ACME agents chosen in accordance with selection criteria set by the system manager.

Your calling program can specify a target DOI using one of the following item codes:

  • ACME$_TARGET_DOI_ID
  • ACME$_TARGET_DOI_NAME

These item codes are used when your program requires that a particular DOI handle your request.

33.4.5.1 DOI Names

The following two DOI names supplied by Compaq are currently defined:

Domain of Interpretation Name Source of the ACME Agent
VMS VMS OpenVMS
Windows NT MSV1_0 Advanced Server

33.4.5.2 When to Use DOI_NAME vs. DOI_ID

The following item codes affect the SYS$ACM[W] system service operations in the same way:

  • ACME$_TARGET_DOI_ID
  • ACME$_TARGET_DOI_NAME

A similar relationship exists between the following item codes:

  • ACME$_CONTEXT_ACME_ID
  • ACME$_CONTEXT_ACME_NAME

The system manager specifies DOI names in configuring the ACME server, although in most cases the system manager uses the registered names specified by a vendor.

DOI IDs are implicitly specified by the system manager by the order in which each is specified for the first time after each boot of the system. That means that a particular DOI ID may have an entirely different meaning on the same machine after the next reboot.

Specifying a DOI_NAME clearly gives better ease-of-use, while specifying a DOI_ID gives slightly better performance with an overhead penalty paid up front to look up a DOI_ID based on a DOI_NAME. Some programs that call the SYS$ACM[W] system service, however, need to perform that lookup in order to interpret the contents of the ACM communications buffer, so in those cases the DOI_ID is already available and can be used in calls to the SYS$ACM[W] system service.

33.4.5.3 Looking Up DOI and ACME IDs

Use the Query function code with a Target DOI ID of 0 (meaning the SYS$ACM[W] system service itself) to determine what DOI_ID corresponds to a given name.

The item list to do this would be as follows:

  • SYS$ACM[W] server query - ID value 0:
    ITMCOD = ACME$_TARGET_DOI_ID
    BUFSIZ = 4
    BUFADR = Address of longword containing 0
  • Query based on ACME name:
    ITMCOD = ACME$_QUERY_KEY_TYPE
    BUFSIZ = 4
    BUFADR = Address of longword containing ACME$K_QUERY_ACME_NAME
  • Specify ACME name:
    ITMCOD = ACME$_QUERY_KEY_VALUE
    BUFSIZ = Characters in ACME name (times 4 if setting ACME$M_UCS2_4)
    BUFADR = Address of buffer containing ACME name
  • Specify ACME ID as the return value:
    ITMCOD = ACME$_QUERY_TYPE
    BUFSIZ = 4
    BUFADR = Address of longword containing ACME$K_QUERY_ACME_ID
  • Specify the output buffer
    ITMCOD = ACME$_QUERY_DATA
    BUFSIZ = 4
    BUFADR = Address of longword to receive the ACME_ID

33.4.6 Determining ACME Information with the Query Function

The general nature of the Query function is that your code supplies the following items:

  • ACME$_TARGET_DOI_ID (or ACME$_TARGET_DOI_NAME)
  • ACME$_QUERY_TYPE
  • ACME$_QUERY_KEY_TYPE
  • ACME$_QUERY_KEY_VALUE

Your program receives back the item ACME$_QUERY_DATA.

Semantics of those items and where the data comes from is entirely up to the ACME agent that you specify as the target of the Query function.

See the documentation for that ACME agent for more information.

33.4.7 Reporting an Event

The general nature of the Event function is that your code supplies the following items:

  • ACME$_EVENT_TYPE
  • ACME$_EVENT_DATA_IN

Your program possibly receives back item ACME$_EVENT_DATA_OUT. Whether ACME$_EVENT_DATA_OUT is supported and the exact nature of what the SYS$ACM[W] system service is supposed to do for an event is up to the ACME agent that you specify as the target of the Event function.

See the documentation for that ACME agent for more information.

33.5 Authentication Scenarios

You can use the SYS$ACM[W] system service to accomplish the following functions:

  • Authenticate a specified user.
  • Change a password.
  • Reauthenticate the current user.
  • Create a process on behalf of a user.

It was possible to perform many of these functions prior to introduction of the SYS$ACM[W] system service by combining the use of the following techniques:

  • SYS$GETUAI
  • SYS$SETUAI
  • SYS$HASH_PASSWORD
  • SYS$SCAN_INTRUSION
  • Modal restriction enforcement (network, batch, interactive, and so on)
  • Checks for account disabled, account expired, and so on

These steps made it difficult to provide a complete and bug-free implementation. Furthermore, such an approach dealt only with traditional VMS password-based authentication rather than including add-on mechanisms. With the introduction of the SYS$ACM[W] system service, those scenarios can be handled in a uniform, supported manner.

33.5.1 Simple User Authentication

If all information is known in advance, a call to SYS$ACMW is quite simple, as in the following example:


        LOCAL
            STATUS,
            ACME_STATUS_BLOCK : VECTOR [4,LONG],
            NON_DIALOGUE_ITMLST : ALIAS_ON_AXP $ITMLST_DECL (ITEMS=2);
        !
        ! Populate that item list
        !
        $ITMLST_INIT(ITMLST = NON_DIALOGUE_ITMLST,
             !
             ! What is the Principal Name
             !
             (ITMCOD = ACME$_PRINCIPAL_NAME_IN,
              BUFSIZ = %CHARCOUNT('JENKINS'),
              BUFADR = UPLIT BYTE('JENKINS')),
             !
             ! What Password was given to this routine ?
             !
             (ITMCOD = ACME$_PASSWORD_1,
              BUFSIZ = .INPUT_STRING [DSC$W_LENGTH],
              BUFADR = .INPUT_STRING [DSC$A_POINTER] ) );
        !
        ! Now call the System Service
        !
        STATUS = $ACMW (EFN=EFN$C_ENF,
                        FUNC=ACME$_FC_AUTHENTICATE_PRINCIPAL,
                        ITMLST=NON_DIALOGUE_ITMLST,
                        ACMSB=ACME_STATUS_BLOCK );

33.5.2 Evaluating Status Codes

After any call to the SYS$ACM[W] system service, you must check the return status from the call and the primary status in the ACM Status Block. Following is a sample check:


IF NOT .STATUS
THEN
    SIGNAL_STOP ( STATUS );

IF NOT .ACME_STATUS_BLOCK [ACMESB$L_STATUS]
AND ( .ACME_STATUS_BLOCK [ACMESB$L_STATUS] NEQ ACME$_OPINCOMPL )
THEN
    BEGIN
    IF .ACME_STATUS_BLOCK [ACMESB$L_ACME_ID] NEQ 0
    THEN
        REPORT_ACME_SPECIFIC_ERROR ( ACME_STATUS_BLOCK )
    ELSE
        IF .ACME_STATUS_BLOCK [ACMESB$L_SECONDARY_STATUS]
           EQL .ACME_STATUS_BLOCK [ACMESB$L_STATUS]
        THEN
            SIGNAL_STOP (
                .ACME_STATUS_BLOCK [ACMESB$L_STATUS] )
        ELSE
            SIGNAL_STOP (
                .ACME_STATUS_BLOCK [ACMESB$L_STATUS], 0,
                .ACME_STATUS_BLOCK [ACMESB$L_SECONDARY_STATUS], 0 );
    END;

The details of handling the field ACMESB$L_ACME_STATUS depend on the nature of the ACME agent indicated in field ACMESB$L_ACME_ID. If that ACME agent is not specifically known to the program that calls the SYS$ACM[W] system service, there is no way to interpret that field. The previous example presumes there is special knowledge regarding at least one ACME agent held in routine REPORT_ACME_SPECIFIC_ERROR, which is not supplied.

33.5.3 Password Change Dialogue

Particularly with the function code ACME$_FC_CHANGE_PASSWORD, you cannot reliably predict all the necessary input at the time of the initial call, because the first password chosen might be found in the password history file or be unacceptable in some other way.

Following is a sample of how you might decode and process a dialogue response:


BIND
    ACMECB = .CONTEXT : BLOCK[,BYTE],
    ITEM_SET = .ACMECB[ACMECB$PS_ITEM_SET] : BLOCKVECTOR[,ACMEIS$K_LENGTH,BYTE],
    RESPONSE_ITEM_COUNTER : INITIAL [0],
    !
    ! A real program should calculate the size for the following
    ! by basing it on .ACMECB[ACMECB$L_ITEM_SET_COUNT].
    !
    RESPONSE_ITEM_LIST : ALIAS_ON_AXP $ITMLST_DECL (ITEMS=9999);
!
! Store a terminator in case there are no input items.
!
RESPONSE_ITEM_LIST [0,ITM$L_TERMINATOR] = 0;
!
! Iterate over Itemset Array
!
INCRU ITEM_SET_INDEX FROM 1 TO .ACMECB[ACMECB$L_ITEM_SET_COUNT] DO
    BEGIN
    BIND
        ITEM_SET_ENTRY = ITEM_SET [.ITEM_SET_INDEX,0,0,0,0],
        ITEM_FLAGS = ITEM_SET_ENTRY [ACMEIS$L_FLAGS] : BLOCK[4,BYTE],
        ITEM_CODE = ITEM_SET_ENTRY [ACMEIS$W_ITEM_CODE] : BLOCK[2,BYTE];
    IF NOT .ITEM_CODE[ACMEIC$V_UCS]
    THEN
        SIGNAL_STOP ( THIS_PROGRAM_HANDLES_ONLY_TEXT );
    IF NOT .ITEM_CODE[ACMEIC$V_OUTPUT]
    THEN
        BEGIN   ! Respond to an input item
        !
        ! Call subroutines to read input and put it in the item list.
        !
        IF .ITEM_FLAGS[ACMEDLOGFLG$V_NOECHO]
        THEN
            !
            ! Read the input - Last parameter (if any) indicates the prompt
            ! to be used on a confirmation read.  That confirmation must
            ! match the initial response before returning here.
            !
            CONSTRUCT_ITEM_NOECHO_FROM_TERMINAL (
                 RESPONSE_ITEM_LIST [.RESPONSE_ITEM_COUNTER,0,0,0,0],
                 .ITEM_SET_ENTRY [acmeis$w_max_length],
                 ITEM_SET_ENTRY [acmeis$q_data_1],
                 ITEM_SET_ENTRY [acmeis$q_data_2] )
        ELSE
            !
            ! Just read the input - Last parameter indicates a default
            ! that will be taken by SYS$ACM if a blank line is supplied.
            !
            CONSTRUCT_ITEM_FROM_TERMINAL (
                 RESPONSE_ITEM_LIST [.RESPONSE_ITEM_COUNTER,0,0,0,0],
                 .ITEM_SET_ENTRY [acmeis$w_max_length],
                 ITEM_SET_ENTRY [acmeis$q_data_1],
                 ITEM_SET_ENTRY [acmeis$q_data_2] );
        !
        ! Advance past this item.
        !
        RESPONSE_ITEM_COUNTER = .RESPONSE_ITEM_COUNTER + 1;
        !
        ! Store a terminator in case this was the last input item.
        !
        RESPONSE_ITEM_LIST [.RESPONSE_ITEM_COUNTER,ITM$L_TERMINATOR] = 0;
        BEGIN
    END;
!
! Now call the System Service again, with the same FUNC argument.
!
! If all the item set entries were for output, we send a null item list.
!
STATUS = $ACMW (EFN=EFN$C_ENF,
                FUNC=ACME$_FC_CHANGE_PASSWORD,
                CONTXT=CONTEXT,
                ITMLST=RESPONSE_ITEM_LIST,
                ACMSB=ACMESB );

This example leaves the details of handling an optional confirmation prompt to the routine CONSTRUCT_ITEM_NOECHO_FROM_TERMINAL, which is not supplied. In addition, the code to process and display output items is not shown.

Confirmation prompts are more common in Change Password than in Authenticate Principal, but the program that calls SYS$ACM[W] system service should be prepared to handle them in either situation (that is, any time dialogue mode is used).


Previous Next Contents Index