How VM:Operator Macros are Authorized for Use

Document ID : KB000055654
Last Modified Date : 14/02/2018
Show Technical Document Details

If your site uses VM:Operator macros, it is important to understand that you must check for the user's authority to run the macro inside the macro itself. Said another way, any user can run a VM:Operator macro if there is no authorization checking. For example, the following macro can be run by any user at your site, which probably is a bad idea:

    /* A poorly written autolog macro */
    parse arg userid 
    'TEST CP AUTOLOG' userid 'DIRECT' 
    exit rc 

A far better approach is to add authorization checks prior to running the AUTOLOG command, as in the following example.

    /* A better written autolog macro */ 
    'TEST PROCESS AUTHORIZE $ALOG' 
    if rc <> 0 then exit -1 
    parse arg userid 
    'TEST CP AUTOLOG' userid 'DIRECT' 
    exit rc 

The PROCESS AUTHORIZE primitive, which is documented in the VM:Operator Programming Guide, checks for authorities encoded into the VMOPER CONFIG file. Using the above example and assuming the name of the macro is ALOG VMOPER, consider the effect of these three records in VMOPER CONFIG:

    AUTHORIZ $ALOG MARGE LISA MAGGIE 
    PREVENT $ALOG HOMER BART 
    AUTHORIZ ALL SMITHERS 

In this example, the three users Marge, Lisa and Maggie are explicitly authorized to use the locally-written tool called ALOG VMOPER. Also, Mr. Smithers is authorized because he has ALL authority, which always includes all locally-written tools. However, Homer and Bart and explicity prevented from running the local tool ALOG VMOPER. And even though Mr. Burns is not mentioned in the config file records, he also is not allowed to run ALOG VMOPER, but only because the macro itself is doing an authorization check.

Remember that VM:Operator will run macros found on any accessed disk. We recommend that you place VM:Operator macros on the operator's 191 A-disk and not onto other public disks, such as the MAINT 19E Y-disk.

Another way to help enforce security of VM:Operator macros is to encode inside the macro itself limits on where the macro can run. For example, you can encode a VM:Operator macro so it only runs from the operator's console itself. Or perhaps you want to write a macro which is for you to use, but not for the operator to use at all. Let's examine the following stub and see how we can pick and choose:

    'TEST TRANSFER TERM' 
    Parse Upper Pull term. 
    term = Translate( term, '40'x, '00'x )                    /* ensure a clean parse */ 
    Select                                                /* command received via ... */ 
    When term = ''         Then Nop                            /* running at start-up */ 
    When term = 'CONSOLE'  Then Nop                             /* OPERATOR's console */ 
    When term = 'DEDICATE' Then Nop                    /* dedicated or dialed console */ 
    When term = 'DISC'     Then Nop                       /* drone on disconnected ID */ 
    When term = 'IUCV'     Then Nop                               /* VMYIAMOP console */ 
    When term = 'LOCAL'    Then Nop                          /* drone on local userid */ 
    When term = 'REMOTE'   Then Nop                         /* drone on remote userid */ 
    When term = 'TERM'     Then Nop                     /* drone, not local or remote */ 
    When term = 'SMSG'     Then Nop                                    /* via CP SMSG */ 
    Otherwise Do 
        Call PUTMSG 'Invalid attempt to perform this command.' 
        Exit 16 
        End 
    End 

In this example the TRANSFER primitive will stack a word describing how the macro was invoked. For example, if the TRANSFER TERM primitive returns "CONSOLE" then the macro was invoked because the command was invoked from the operator's main console. On the other hand, if TRANSFER TERM returns "IUCV" then the macro is being invoked by a user running the VMYIAMOP command on his or her personal ID. If the user is trying to issue the macro from the OPERATOR command on his or her personal ID then TRANSFER TERM will return either "DISC", "LOCAL", "REMOTE" or "TERM". You can review more information about the TRANSFER primitive in the VM:Operator Programming Guide.

The above example will allow a macro to be used no matter how it was invoked. So the code adds no additional security.

In our next example let's enforce a macro's use from the operator's console alone. Change the "select" block to:

    Select                                                /* command received via ... */ 
    When term = 'CONSOLE'  Then Nop                             /* OPERATOR's console */ 
    Otherwise Do 
        Call PUTMSG 'Invalid attempt to perform this command.' 
        Exit 16 
        End 
    End 

The above example ensures that the macro can only be run from the operator's ID itself. That is, the MAINOPER window alone. This level of security is enforced even if the user attempting to invoke the macro has an AUTHORIZ ALL record in the VMOPER CONFIG file.

Let's imagine that we want to write a macro which we don't want the operator to run. In this case we can enforce a macro's use from VMYIAMOP alone. To do so change the "select" block to:

    Select                                                /* command received via ... */ 
    When term = 'IUCV'     Then Nop                               /* VMYIAMOP console */ 
    Otherwise Do 
        Call PUTMSG 'Invalid attempt to perform this command.' 
        Exit 16 
        End 
    End 

Perhaps we want to write a command which can only be used from the CMS command line, via the OPERATOR command. In this case code:

    Select                                                /* command received via ... */ 
    When term = 'DISC'     Then Nop                       /* drone on disconnected ID */ 
    When term = 'LOCAL'    Then Nop                          /* drone on local userid */ 
    When term = 'REMOTE'   Then Nop                         /* drone on remote userid */ 
    When term = 'TERM'     Then Nop                     /* drone, not local or remote */ 
    Otherwise Do 
        Call PUTMSG 'Invalid attempt to perform this command.' 
        Exit 16 
        End 
    End 

You can mix and match the various "when" phrases to get the exact limits you need for your site.

Using combinations of the above approaches can ensure that VM:Operator macros can only be run as intended. Finally, be sure to do adequate testing until you are satisfied that the macro is properly authorized to ensure proper use.

Please note that there is a typo in the VM:Operator System Administrator's Guide which may lead some users to misunderstand how VM:Operator macros are authorized for use. Chapter 13, "Troubleshooting" has the incorrect example code:

    /* Autolog Macro */ 
    ... 
    if rc=0 then exit -1 
    ... 
    should state 
    if rc <> 0 then exit -1