Steps for using the SMTP server exits

Use the SMTP server exit to check and subsequently accept or reject mail inbound from a TCP/IP network or mail outbound from the JES spool. For example, you can code an exit to check the MAIL FROM: string on outbound mail or to control the influx of unwanted inbound mail (commonly referred to as spam).

Tip: The exits described in this topic are also used by the CSSMTP application for checking outbound mail only. See Communications Server SMTP application for more information.
The SMTP server dynamically determines if an SMTP exit program exists. This determination is based upon the SMTP exit program association with the name token EZBTCPIPSMTPEXIT using the MVS™ SETPROG command. So, the presence of the SMTP exit program allows the SMTP server to call the exit program for inbound TCP/IP connection data. If you determine that the exit program needs to be called to interrogate data coming from the JES spool, follow these steps:
  1. Add the EXITDIRECTION statement and the appropriate parameters to the SMTP configuration. Also, stop and restart the SMTP server in order to recognize the new configuration settings.

    _________________________________________________________________

  2. In order to work correctly with the JES connection, add code to the user exit program.
    Rules:
    • The JES connection ID is always 257.
    • The field (EZBPIPV4) representing the remote IP address is always zero for the JES connection.
    • For TCP/IP connections, the field (EZBPTOKP) representing the SAF token information is always zero.

    If SAF token information is requested, the field EZBPTOKP contains the address of the token. However, this field can be zero if the SMTP server was unable to retrieve the SAF token from JES. The exit program needs to be coded to handle this situation. The SAF token length is 80 bytes and the SAF token version is 1. The SAF token provides information about the submitting user ID and the submitter node of the JES data. This data can be compared to the sender information about the MAIL FROM: string. For more information about what is provided in the SAF token, see the RUTKN information in z/OS Security Server RACF Data Areas.

    _________________________________________________________________

  3. Recompile the user exit program with the version 2 copy of the EZBZSMTP DSECT. This picks up the changes in the parameter list.

    _________________________________________________________________

  4. Ensure that the user ID specified on the POSTMASTER statement in the SMTP configuration file is a valid user ID.
    Requirement: This user ID and host must be able to receive mail.

    When mail is rejected by the SMTP exit program for the JES connection ID, it is always returned to the POSTMASTER. The POSTMASTER must determine what happens to the rejected JES data. After the SMTP exit program rejects the JES data, the entire spool file is rejected, which might include multiple notes. Depending on how the JES data is spooled, this might be a large amount of data.

    The POSTMASTER can modify the data and resend it to SMTP, or it can discard the data. The SMTP exit program policies determine whether or not the POSTMASTER receives large quantities of mail that require review. When the SMTP exit program rejects mail from a TCP/IP connection, the remote SMTP client determines what happens to the rejected mail. In this case, the mail becomes undeliverable and might be returned to the originator.

    _________________________________________________________________

If you run the exit program in both directions, performance might be impacted.

Tip: If you want the exit program to interrogate only inbound TCP/IP connections, do not make any configuration changes.

If the SMTP server receives mail from a TCP/IP network, and then sends it out on a TCP/IP connection (relaying the mail), the SMTP server invokes the exit program only one time on the inbound path.

The exit should be written in Assembler Language. Standard z/OS® Assembler entry and exit linkage must be used. See z/OS MVS Programming: Assembler Services Guide for the linkage conventions.

The exit is invoked with the settings shown in Table 1.

Table 1. SMTP user exit settings
Authorization Problem state
Dispatchable Unit Mode Task
Cross memory mode PASN=HASN
Amode 31–bit
ASC mode Primary address space control (ASC) mode
Interrupt status Enabled for interrupts
Locks Unlocked
On entry to the exit, the register contents are:
Register 0
Used as a work register by the system
Register 1
Address of the exit's input parameter list (see Table 2)
Registers 2-12
Unassigned
Register 13
Address of an 18-word save area
Register 14
Return address
Register 15
Address of the exit routine

The exits input parameter list contains the information shown in Table 2. An assembler macro is available to provide you with a DSECT describing this area. The name of the macro is EZBZSMTP and the macro resides in SEZACMAC. It enables an optional label but has no operands. It provides symbolic names for the 3 return codes and 18 action codes. The labels are as shown in Table 2.

Table 2. SMTP server exit input parameter list
Label name Width/Value Description
Parameter list variables
EZBZSMTP   DSECT Name
EZBPVERS (See note 1) 1 Fullword Version number
EZBPACTN (See note 2) 1 Fullword Action code
EZBPUSER (See note 3) 1 Fullword Returned Reg15 of initialization call
EZBPCNID (See note 4) 1 Fullword Connection ID
EZBPTOKP (See note 17) 1 Fullword Address of SAF (security) token
  2 Fullwords Reserved for future use
EZBPIPV4 (See note 6) 1 Fullword IP addr of remote SMTP
EZBPDLEN (See note 7) 1 Fullword Length of data in buffer
EZBPBUFF (See note 8) 1 Fullword Buffer address
Constants
EZBRAGN 0 Return code to continue
EZBRACC 4 Return code to accept mail
EZBRREJ 8 Return code to reject mail
Action codes
EZBAINIT 1 Initialization call (See note 9)
EZBATERM 2 Termination call (See note 10)
EZBADATA 3 SMTP DATA command
EZBAEXPN 4 SMTP EXPN (expand) command
EZBAHELO 5 SMTP HELO (hello) command
EZBAHELP 6 SMTP HELP command
EZBAMAIL 7 SMTP MAIL command
EZBANOOP 8 SMTP NOOP command (See note 11)
EZBAQUEU 9 IBM® SMTP QUEU (queue) command
EZBAQUIT 10 SMTP QUIT command (See note 12)
EZBARCPT 11 SMTP RCPT (recipient) command
EZBARSET 12 SMTP RSET (Reset) command (See note 13)
EZBATICK 13 IBM SMTP TICK command
EZBAVERB 14 IBM SMTP VERB command
EZBAVRFY 15 SMTP VRFY (Verify) command
EZBADBUF 16 Data buffer (See note 14)
EZBAEODB 17 End of data buffers (last chance) (See note 15)
EZBACONN 18 End of connection (See note 16)
Notes:
  1. A word containing a version number. The value is one when the exit program is called for INBOUND mail only. The value is two when the exit program is called for BOTH (inbound and outbound) mail.
  2. A word-aligned word containing an action code describing the buffer contents (if any).
  3. A word containing the user supplied token from the initialization call.
  4. A word containing a connection identifier number to distinguish between concurrent connections. The connection ID representing the JES spool data is always 257.
  5. Two unused words (reserved space).
  6. A word containing the IP address of the connecting remote SMTP. It contains 0 if the connection ID is 257 (JES connection ID).
  7. A word containing the actual length of data in the buffer. If the buffer length is meaningless for the action code, the length is set to 0.
  8. A word containing a 31–bit address that points to the actual buffer. If the buffer length is 0, this parameter should not be used.
  9. Buffer is empty, expect return token in R15.
  10. Buffer is empty, application shutting down, exit return code is ignored. This call (and all others) might not occur during abnormal termination.
  11. Exit return code is ignored whenever this command is detected.
  12. Exit return code is ignored.
  13. Exit return code is ignored.
  14. Data buffer (there is no command associated with this) approximately 1 024 bytes of data or less. The data are in EBCDIC, but might be in an multicultural support mode (non-English).
  15. End of data marker (there is no command associated with this and the buffer contents are meaningless). This is the last chance to reject this message.
  16. TCP/IP connection terminated or end of file for JES spool data.
  17. If SAF information is requested using the EXITDIRECTION statement in the SMTP configuration, the SMTP server sets this field to a 31-bit address that points to the SAF (security) token information. If the SMTP server was unable to retrieve the SAF token or if the EXITDIRECTION statement is not configured, this field contains 0. For TCP/IP connections, this field is always 0.

There are two control invocations of the SMTP user exit. One for initialization, and the other for termination. On return from the initialization call, the contents of register 15 is treated as a 4-byte user token that is returned on all other exit invocations. See Table 2 for more information. The user token is not used by SMTP, but only passed on subsequent calls to allow a reentrant exit to have static data (using getmain or some other method). It is expected that certain data sets might be read during the initialization call and that tables of known spamming Internet addresses might be constructed at this time for later use. The termination call allows report generation or any other clean-up activity that the exit might do prior to the stopping of SMTPPROC under normal termination logic.

There are three supported return code values which the exit program might set. For certain action codes such as initialization (EZBAINT), termination (EZBATERM) and end of connection (EZBACONN) the return code value is ignored. The returned value and expected meanings are as follows:

0
Call user-supplied exit program again.
4
Accept this message or command and do not call again for this message.
8
Reject message or command and do not call again for this message.
  • During processing of SMTP commands, the reply code 550 service denied due to user supplied exit is generated immediately.
  • During note data processing (action code = 16), the reply code 550 service denied due to user supplied exit is generated when the end of data marker (action code = 17 ) is received.

Return codes that are not valid are converted to a 0, and the exit is called again.

Tip: Certain commands should not be rejected, because they can cause unpredictable results with the partner SMTP application.
Rule: Certain commands, such as NOOP, QUIT, and RSET should always be accepted.

The connection identifier is a unique number during the life of the connection. You can use it to distinguish between multiple concurrent connections that can be present. Each has its own state information in SMTPPROC, and if the exit wants to keep any state information, this field can be used to keep each message's state separate. Connection identifiers normally become available for reuse after a QUIT command or the end of connection (action code 18), or both, occur. They normally first appear with a HELO command.

The buffer contents for action codes 3 through 15 contain the SMTP command.

The buffer contains data that has been translated using the EBCDIC encoding tables configured for the SMTPPROC. Data buffers might not be in English and might contain NLS characters.

Unknown commands are rejected by SMTPPROC and the exit is not called. The buffer normally contains the SMTP command. See RFC 821 for exact spellings and format.

Guideline: The SMTP command can appear in either upper, lower, or mixed case.

The initialization and termination calls do not have a connection number. The return code from the initialization call is not checked, but placed in the ezbpuser field. The return code from the termination call is moot. These calls are always active if the exit is active.

Interaction between SMTP and user exit program

During an active connection, SMTP determines whether the user exit program is called again based on the return code passed back to SMTP from the previous invocation of the exit.

The user exit is not called again for the affected connection until the resetting action codes are received, and only if the ezbracc or the ezbrrej return codes are received from the exit from a connection-oriented call. The accept or reject state might remain in effect for only the current call however.

In Table 3, the following codes are not sent to the exit if the current state is accept or reject and do not change the state.

Table 3. Exit action codes and values (Part 1)
Action code Value
3 DATA
4 EXPN
6 HELP
8 NOOP
9 QUEU
11 RCPT
13 TICK
14 VERB
15 VRFY
16 data buffers

In Table 4, the following codes are not sent to the exit, but they ensure that the next command (if any) goes to the exit as it resets the next state to ezbragn.

Table 4. Exit action codes and values (Part 2)
Action code Value
10 QUIT
12 RSET
17 End of data buffers (final chance)

In Table 5, the following is always sent to the exit if it is active, and the return code received determines the new state.

Table 5. Exit action codes and values (Part 3)
Action code Value
5 HELO
7 MAIL
18 Connection closed (termination of individual connection). Connection number available for reuse and state is reset to ezbragn.